@cleocode/core 2026.6.14 → 2026.6.17
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/dist/check/pr-gate.d.ts +6 -2
- package/dist/check/pr-gate.d.ts.map +1 -1
- package/dist/check/pr-gate.js +14 -32
- package/dist/check/pr-gate.js.map +1 -1
- package/dist/config/config-repair.d.ts +70 -0
- package/dist/config/config-repair.d.ts.map +1 -0
- package/dist/config/config-repair.js +248 -0
- package/dist/config/config-repair.js.map +1 -0
- package/dist/config/registry.d.ts.map +1 -1
- package/dist/config/registry.js +4 -4
- package/dist/config/registry.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -10
- package/dist/config.js.map +1 -1
- package/dist/docs/export-document.js +58 -16
- package/dist/docs/export-document.js.map +2 -2
- package/dist/gc/cleanup.d.ts +23 -8
- package/dist/gc/cleanup.d.ts.map +1 -1
- package/dist/gc/cleanup.js +287 -22
- package/dist/gc/cleanup.js.map +1 -1
- package/dist/gc/janitor.d.ts +149 -0
- package/dist/gc/janitor.d.ts.map +1 -0
- package/dist/gc/janitor.js +760 -0
- package/dist/gc/janitor.js.map +1 -0
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +3 -0
- package/dist/internal.js.map +1 -1
- package/dist/llm/cli-ops.d.ts +31 -4
- package/dist/llm/cli-ops.d.ts.map +1 -1
- package/dist/llm/cli-ops.js +110 -26
- package/dist/llm/cli-ops.js.map +1 -1
- package/dist/llm/credential-pool.d.ts +62 -0
- package/dist/llm/credential-pool.d.ts.map +1 -1
- package/dist/llm/credential-pool.js +161 -0
- package/dist/llm/credential-pool.js.map +1 -1
- package/dist/llm/cross-provider-selector.d.ts +254 -0
- package/dist/llm/cross-provider-selector.d.ts.map +1 -0
- package/dist/llm/cross-provider-selector.js +635 -0
- package/dist/llm/cross-provider-selector.js.map +1 -0
- package/dist/llm/index.d.ts +2 -0
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +1 -0
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/local-model-fit.d.ts +260 -0
- package/dist/llm/local-model-fit.d.ts.map +1 -0
- package/dist/llm/local-model-fit.js +563 -0
- package/dist/llm/local-model-fit.js.map +1 -0
- package/dist/llm/plugin-facade.js +883 -231
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/llm/provider-registry/builtin/ollama.d.ts +18 -0
- package/dist/llm/provider-registry/builtin/ollama.d.ts.map +1 -1
- package/dist/llm/provider-registry/builtin/ollama.js +20 -2
- package/dist/llm/provider-registry/builtin/ollama.js.map +1 -1
- package/dist/llm/role-resolver.d.ts.map +1 -1
- package/dist/llm/role-resolver.js +45 -10
- package/dist/llm/role-resolver.js.map +1 -1
- package/dist/llm/transports/codex-responses.d.ts +111 -88
- package/dist/llm/transports/codex-responses.d.ts.map +1 -1
- package/dist/llm/transports/codex-responses.js +456 -258
- package/dist/llm/transports/codex-responses.js.map +1 -1
- package/dist/release/index.d.ts +2 -2
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +1 -1
- package/dist/release/index.js.map +1 -1
- package/dist/release/reconcile.d.ts +97 -0
- package/dist/release/reconcile.d.ts.map +1 -1
- package/dist/release/reconcile.js +412 -5
- package/dist/release/reconcile.js.map +1 -1
- package/dist/resources/backend.d.ts +155 -0
- package/dist/resources/backend.d.ts.map +1 -0
- package/dist/resources/backend.js +23 -0
- package/dist/resources/backend.js.map +1 -0
- package/dist/resources/linux-backend.d.ts +167 -0
- package/dist/resources/linux-backend.d.ts.map +1 -0
- package/dist/resources/linux-backend.js +259 -0
- package/dist/resources/linux-backend.js.map +1 -0
- package/dist/resources/monitor.d.ts +230 -0
- package/dist/resources/monitor.d.ts.map +1 -0
- package/dist/resources/monitor.js +255 -0
- package/dist/resources/monitor.js.map +1 -0
- package/dist/resources/spawn-wrapper.d.ts +265 -0
- package/dist/resources/spawn-wrapper.d.ts.map +1 -0
- package/dist/resources/spawn-wrapper.js +304 -0
- package/dist/resources/spawn-wrapper.js.map +1 -0
- package/dist/selfimprove/budget.d.ts +11 -2
- package/dist/selfimprove/budget.d.ts.map +1 -1
- package/dist/selfimprove/budget.js +11 -2
- package/dist/selfimprove/budget.js.map +1 -1
- package/dist/selfimprove/fix-gen-context.d.ts +172 -0
- package/dist/selfimprove/fix-gen-context.d.ts.map +1 -0
- package/dist/selfimprove/fix-gen-context.js +218 -0
- package/dist/selfimprove/fix-gen-context.js.map +1 -0
- package/dist/selfimprove/fix-gen.d.ts +285 -0
- package/dist/selfimprove/fix-gen.d.ts.map +1 -0
- package/dist/selfimprove/fix-gen.js +346 -0
- package/dist/selfimprove/fix-gen.js.map +1 -0
- package/dist/selfimprove/op-source-map.d.ts +92 -0
- package/dist/selfimprove/op-source-map.d.ts.map +1 -0
- package/dist/selfimprove/op-source-map.js +187 -0
- package/dist/selfimprove/op-source-map.js.map +1 -0
- package/dist/selfimprove/probe-helper.d.ts +61 -0
- package/dist/selfimprove/probe-helper.d.ts.map +1 -0
- package/dist/selfimprove/probe-helper.js +64 -0
- package/dist/selfimprove/probe-helper.js.map +1 -0
- package/dist/selfimprove/run-loop.d.ts +44 -4
- package/dist/selfimprove/run-loop.d.ts.map +1 -1
- package/dist/selfimprove/run-loop.js +73 -6
- package/dist/selfimprove/run-loop.js.map +1 -1
- package/dist/selfimprove/scenarios/seeded-code-regression/golden.json +18 -0
- package/dist/selfimprove/scenarios/seeded-code-regression/scenario.json +12 -0
- package/dist/sentient/cross-project-hygiene.d.ts +11 -2
- package/dist/sentient/cross-project-hygiene.d.ts.map +1 -1
- package/dist/sentient/cross-project-hygiene.js +73 -10
- package/dist/sentient/cross-project-hygiene.js.map +1 -1
- package/dist/sentient/daemon.d.ts.map +1 -1
- package/dist/sentient/daemon.js +7 -2
- package/dist/sentient/daemon.js.map +1 -1
- package/dist/sentient/worktree-dispatch.d.ts.map +1 -1
- package/dist/sentient/worktree-dispatch.js +8 -1
- package/dist/sentient/worktree-dispatch.js.map +1 -1
- package/dist/setup/index.d.ts +1 -0
- package/dist/setup/index.d.ts.map +1 -1
- package/dist/setup/index.js +1 -0
- package/dist/setup/index.js.map +1 -1
- package/dist/setup/sections/models-roles.d.ts +32 -1
- package/dist/setup/sections/models-roles.d.ts.map +1 -1
- package/dist/setup/sections/models-roles.js +118 -19
- package/dist/setup/sections/models-roles.js.map +1 -1
- package/dist/setup/whoami-summary.d.ts +34 -0
- package/dist/setup/whoami-summary.d.ts.map +1 -0
- package/dist/setup/whoami-summary.js +106 -0
- package/dist/setup/whoami-summary.js.map +1 -0
- package/dist/spawn/branch-lock.d.ts.map +1 -1
- package/dist/spawn/branch-lock.js +7 -1
- package/dist/spawn/branch-lock.js.map +1 -1
- package/dist/store/attachment-repair.d.ts +110 -0
- package/dist/store/attachment-repair.d.ts.map +1 -0
- package/dist/store/attachment-repair.js +326 -0
- package/dist/store/attachment-repair.js.map +1 -0
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +24 -7
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/tasks/evidence.d.ts +34 -2
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +293 -35
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/verification/verify-tools.d.ts.map +1 -1
- package/dist/verification/verify-tools.js +5 -6
- package/dist/verification/verify-tools.js.map +1 -1
- package/package.json +22 -12
- package/templates/workflows/release-prepare.yml.tmpl +48 -2
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-improvement probe helper — selfimprove.probe op (T11988).
|
|
3
|
+
*
|
|
4
|
+
* This tiny module exists to give the seeded-code-regression scenario a
|
|
5
|
+
* **real, patchable code bug** for end-to-end fix-gen proof. The function
|
|
6
|
+
* {@link probeVersion} is supposed to return `1` (the canonical probe API
|
|
7
|
+
* version), but ships with an intentional off-by-one (`return 2`) so that a
|
|
8
|
+
* live replay of the `seeded-code-regression` scenario diverges from the
|
|
9
|
+
* golden (`version: 1`) and the LLM can produce a correct one-line unified
|
|
10
|
+
* diff to fix it.
|
|
11
|
+
*
|
|
12
|
+
* ### Why a dedicated file?
|
|
13
|
+
*
|
|
14
|
+
* The seeded bug must be:
|
|
15
|
+
* 1. **In a repo-relative path** the op-source-map can register under
|
|
16
|
+
* `selfimprove.probe` so the fix-gen context loader includes it in the
|
|
17
|
+
* LLM prompt.
|
|
18
|
+
* 2. **Minimal** — the simplest possible off-by-one so the model cannot
|
|
19
|
+
* rationally refuse (`NO_PATCH`).
|
|
20
|
+
* 3. **Self-contained** — no live DB, no side effects; the probe op
|
|
21
|
+
* never mutates.
|
|
22
|
+
*
|
|
23
|
+
* ### Fixing the bug
|
|
24
|
+
*
|
|
25
|
+
* Change `return 2` → `return 1` in {@link probeVersion}. This is the EXACT
|
|
26
|
+
* one-line fix the self-improvement loop's LLM fix-gen stage should propose
|
|
27
|
+
* when replaying the seeded scenario.
|
|
28
|
+
*
|
|
29
|
+
* @module @cleocode/core/selfimprove/probe-helper
|
|
30
|
+
* @task T11988
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Return the canonical probe API version.
|
|
34
|
+
*
|
|
35
|
+
* Expected value: `1`.
|
|
36
|
+
*
|
|
37
|
+
* @returns The probe version number.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* probeVersion(); // => 1 (expected)
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @bug SEEDED — currently returns `2` instead of `1` (T11988 intentional).
|
|
45
|
+
* The seeded-code-regression scenario golden asserts `version: 1`; the
|
|
46
|
+
* mismatch is the regression the fix-gen LLM prompt targets.
|
|
47
|
+
*/
|
|
48
|
+
export declare function probeVersion(): number;
|
|
49
|
+
/**
|
|
50
|
+
* Build the `selfimprove.probe` response payload.
|
|
51
|
+
*
|
|
52
|
+
* Returns `{ probe: 'ok', version: <probeVersion()> }` — the envelope `data`
|
|
53
|
+
* block the `selfimprove.probe` query op emits.
|
|
54
|
+
*
|
|
55
|
+
* @returns The probe response payload.
|
|
56
|
+
*/
|
|
57
|
+
export declare function buildProbePayload(): {
|
|
58
|
+
probe: 'ok';
|
|
59
|
+
version: number;
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=probe-helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-helper.d.ts","sourceRoot":"","sources":["../../src/selfimprove/probe-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAIrC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAEpE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-improvement probe helper — selfimprove.probe op (T11988).
|
|
3
|
+
*
|
|
4
|
+
* This tiny module exists to give the seeded-code-regression scenario a
|
|
5
|
+
* **real, patchable code bug** for end-to-end fix-gen proof. The function
|
|
6
|
+
* {@link probeVersion} is supposed to return `1` (the canonical probe API
|
|
7
|
+
* version), but ships with an intentional off-by-one (`return 2`) so that a
|
|
8
|
+
* live replay of the `seeded-code-regression` scenario diverges from the
|
|
9
|
+
* golden (`version: 1`) and the LLM can produce a correct one-line unified
|
|
10
|
+
* diff to fix it.
|
|
11
|
+
*
|
|
12
|
+
* ### Why a dedicated file?
|
|
13
|
+
*
|
|
14
|
+
* The seeded bug must be:
|
|
15
|
+
* 1. **In a repo-relative path** the op-source-map can register under
|
|
16
|
+
* `selfimprove.probe` so the fix-gen context loader includes it in the
|
|
17
|
+
* LLM prompt.
|
|
18
|
+
* 2. **Minimal** — the simplest possible off-by-one so the model cannot
|
|
19
|
+
* rationally refuse (`NO_PATCH`).
|
|
20
|
+
* 3. **Self-contained** — no live DB, no side effects; the probe op
|
|
21
|
+
* never mutates.
|
|
22
|
+
*
|
|
23
|
+
* ### Fixing the bug
|
|
24
|
+
*
|
|
25
|
+
* Change `return 2` → `return 1` in {@link probeVersion}. This is the EXACT
|
|
26
|
+
* one-line fix the self-improvement loop's LLM fix-gen stage should propose
|
|
27
|
+
* when replaying the seeded scenario.
|
|
28
|
+
*
|
|
29
|
+
* @module @cleocode/core/selfimprove/probe-helper
|
|
30
|
+
* @task T11988
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Return the canonical probe API version.
|
|
34
|
+
*
|
|
35
|
+
* Expected value: `1`.
|
|
36
|
+
*
|
|
37
|
+
* @returns The probe version number.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* probeVersion(); // => 1 (expected)
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @bug SEEDED — currently returns `2` instead of `1` (T11988 intentional).
|
|
45
|
+
* The seeded-code-regression scenario golden asserts `version: 1`; the
|
|
46
|
+
* mismatch is the regression the fix-gen LLM prompt targets.
|
|
47
|
+
*/
|
|
48
|
+
export function probeVersion() {
|
|
49
|
+
// SEEDED BUG (T11988): should be `return 1` — intentional off-by-one for
|
|
50
|
+
// the seeded-code-regression end-to-end fix-gen scenario.
|
|
51
|
+
return 2;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build the `selfimprove.probe` response payload.
|
|
55
|
+
*
|
|
56
|
+
* Returns `{ probe: 'ok', version: <probeVersion()> }` — the envelope `data`
|
|
57
|
+
* block the `selfimprove.probe` query op emits.
|
|
58
|
+
*
|
|
59
|
+
* @returns The probe response payload.
|
|
60
|
+
*/
|
|
61
|
+
export function buildProbePayload() {
|
|
62
|
+
return { probe: 'ok', version: probeVersion() };
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=probe-helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-helper.js","sourceRoot":"","sources":["../../src/selfimprove/probe-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY;IAC1B,yEAAyE;IACzE,0DAA0D;IAC1D,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -17,8 +17,15 @@
|
|
|
17
17
|
* 4. on a regression, **emit ONE DHQ** row via the leased
|
|
18
18
|
* {@link "./dhq-adapter.js".DhqAdapter} (UPSERT under
|
|
19
19
|
* `withWriterLease('project','bulk',…)`) — ONLY when `execute` is set;
|
|
20
|
+
* 4b. **generate a fix** ({@link "./fix-gen.js".generateFixPatch}, T11975) — ONLY
|
|
21
|
+
* when `execute` AND `CLEO_PI_RUNNER_ENABLED=1`. Drives the LLM strictly via
|
|
22
|
+
* the E9 chokepoint to produce a unified-diff patch at the path the egress
|
|
23
|
+
* expects (`<cwd>/selfimprove-<scenario>.patch`). Degrades gracefully (no
|
|
24
|
+
* patch ⇒ the egress guard skips the PR); the outcome is recorded back onto
|
|
25
|
+
* the DHQ row. NEVER throws a rogue mutation, NEVER auto-merges;
|
|
20
26
|
* 5. **open ONE DRAFT PR** ({@link "./draft-pr.js".openDraftPr}, dry-run unless
|
|
21
|
-
* `execute`) and record its URL back on the DHQ row
|
|
27
|
+
* `execute`) and record its URL back on the DHQ row — fires only when the
|
|
28
|
+
* fix-gen stage wrote a patch file (the existing `existsSync` egress guard).
|
|
22
29
|
*
|
|
23
30
|
* Self-dogfooding guardrails (NON-NEGOTIABLE, P5 spec §B.7):
|
|
24
31
|
* - **Default OFF.** Mutation + egress require `opts.execute === true`. Without
|
|
@@ -30,8 +37,12 @@
|
|
|
30
37
|
* - **Budget caps** (in-code): `maxTokens` / `maxUsd` / `maxPrs = 1` /
|
|
31
38
|
* `maxWorktrees = 1`, checked PRE-FLIGHT before each costed step. `MemoryMax=32G`
|
|
32
39
|
* is an operational launch-wrapper, not an in-code cap.
|
|
33
|
-
* - **
|
|
34
|
-
*
|
|
40
|
+
* - **Fix-gen is GATED + DRAFT-PR-ONLY (T11975).** The autonomous fix-generation
|
|
41
|
+
* stage runs ONLY behind BOTH `execute` AND `CLEO_PI_RUNNER_ENABLED=1` (the
|
|
42
|
+
* same gates guarding the rest of the loop). It produces a candidate patch via
|
|
43
|
+
* the E9 LLM chokepoint and lets the EXISTING egress open a DRAFT PR — NEVER
|
|
44
|
+
* an auto-merge, NEVER an end-user mode, NEVER a `main` push. A failed or empty
|
|
45
|
+
* fix-gen degrades to "no patch" and the egress simply skips the PR.
|
|
35
46
|
*
|
|
36
47
|
* CORE-first: this engine lives in `core` and owns the `ReplayDispatch` port TYPE;
|
|
37
48
|
* the cleo dispatch handler supplies the concrete adapter (dependency inversion —
|
|
@@ -45,8 +56,9 @@ import { type ExecutionEnvBackend } from '../llm/pi/resolve-execution-env.js';
|
|
|
45
56
|
import { type ToolGuard } from '../tools/guard.js';
|
|
46
57
|
import { type CircuitBreakerState, DEFAULT_BUDGET, type SelfImproveBudget } from './budget.js';
|
|
47
58
|
import { type DhqAdapter } from './dhq-adapter.js';
|
|
48
|
-
import { type DraftPrResult } from './draft-pr.js';
|
|
59
|
+
import { type CommandRunner, type DraftPrResult } from './draft-pr.js';
|
|
49
60
|
import { type DiffEntry } from './envelope-diff.js';
|
|
61
|
+
import { type FixGenerator, type FixGenResult } from './fix-gen.js';
|
|
50
62
|
import { type ReplayDispatch } from './replay.js';
|
|
51
63
|
/** Options for {@link runSelfImprove}. */
|
|
52
64
|
export interface RunSelfImproveOptions {
|
|
@@ -87,6 +99,27 @@ export interface RunSelfImproveOptions {
|
|
|
87
99
|
readonly gateRedCheck?: () => Promise<boolean>;
|
|
88
100
|
/** Test seam: inject a DHQ adapter (defaults to the real leased adapter). */
|
|
89
101
|
readonly adapter?: DhqAdapter;
|
|
102
|
+
/**
|
|
103
|
+
* Test seam: inject the fix generator (the LLM dependency). Defaults to the real
|
|
104
|
+
* {@link "./fix-gen.js".createLlmFixGenerator} backed by the E9 chokepoint — unit
|
|
105
|
+
* tests inject a deterministic fake returning a canned patch so NO real LLM is
|
|
106
|
+
* reached. The fix-gen stage only runs when BOTH `execute` is set AND the
|
|
107
|
+
* Pi-runner gate (`CLEO_PI_RUNNER_ENABLED=1`) is on, unless `piRunnerEnabled` is
|
|
108
|
+
* supplied (test seam) to override the env read.
|
|
109
|
+
*/
|
|
110
|
+
readonly fixGenerator?: FixGenerator;
|
|
111
|
+
/**
|
|
112
|
+
* Test seam: override the `CLEO_PI_RUNNER_ENABLED` env gate that arms fix-gen.
|
|
113
|
+
* Defaults to `process.env.CLEO_PI_RUNNER_ENABLED === '1'`. Supplied explicitly
|
|
114
|
+
* by tests so the deterministic fake runs without mutating process env.
|
|
115
|
+
*/
|
|
116
|
+
readonly piRunnerEnabled?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Test seam: inject the draft-PR egress command runner (captures the git/gh
|
|
119
|
+
* shell-out). Defaults to the real `execFileSync`-backed runner. Supplied by
|
|
120
|
+
* tests so the capstone proves the egress WITHOUT a real `gh`/`git` invocation.
|
|
121
|
+
*/
|
|
122
|
+
readonly draftPrRun?: CommandRunner;
|
|
90
123
|
/** Test seam: inject the guard backing the in-process fallback env. */
|
|
91
124
|
readonly guard?: ToolGuard;
|
|
92
125
|
/** Test seam: inject the run id (defaults to a timestamped id). */
|
|
@@ -120,6 +153,13 @@ export interface SelfImproveResult {
|
|
|
120
153
|
readonly questionHash: string | null;
|
|
121
154
|
/** The draft-PR egress result, or `null` when none fired (green / dry-run-no-egress). */
|
|
122
155
|
readonly draftPr: DraftPrResult | null;
|
|
156
|
+
/**
|
|
157
|
+
* The fix-generation outcome (T11975), or `null` when the stage did not run
|
|
158
|
+
* (green run, dry-run, gate off, or breaker tripped before persist). `'written'`
|
|
159
|
+
* means a candidate patch was produced and the egress was armed; `'skipped'`
|
|
160
|
+
* means fix-gen degraded gracefully (no patch ⇒ no PR).
|
|
161
|
+
*/
|
|
162
|
+
readonly fixGen: FixGenResult | null;
|
|
123
163
|
/** The final circuit-breaker state. */
|
|
124
164
|
readonly breaker: CircuitBreakerState;
|
|
125
165
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-loop.d.ts","sourceRoot":"","sources":["../../src/selfimprove/run-loop.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"run-loop.d.ts","sourceRoot":"","sources":["../../src/selfimprove/run-loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,8 +17,15 @@
|
|
|
17
17
|
* 4. on a regression, **emit ONE DHQ** row via the leased
|
|
18
18
|
* {@link "./dhq-adapter.js".DhqAdapter} (UPSERT under
|
|
19
19
|
* `withWriterLease('project','bulk',…)`) — ONLY when `execute` is set;
|
|
20
|
+
* 4b. **generate a fix** ({@link "./fix-gen.js".generateFixPatch}, T11975) — ONLY
|
|
21
|
+
* when `execute` AND `CLEO_PI_RUNNER_ENABLED=1`. Drives the LLM strictly via
|
|
22
|
+
* the E9 chokepoint to produce a unified-diff patch at the path the egress
|
|
23
|
+
* expects (`<cwd>/selfimprove-<scenario>.patch`). Degrades gracefully (no
|
|
24
|
+
* patch ⇒ the egress guard skips the PR); the outcome is recorded back onto
|
|
25
|
+
* the DHQ row. NEVER throws a rogue mutation, NEVER auto-merges;
|
|
20
26
|
* 5. **open ONE DRAFT PR** ({@link "./draft-pr.js".openDraftPr}, dry-run unless
|
|
21
|
-
* `execute`) and record its URL back on the DHQ row
|
|
27
|
+
* `execute`) and record its URL back on the DHQ row — fires only when the
|
|
28
|
+
* fix-gen stage wrote a patch file (the existing `existsSync` egress guard).
|
|
22
29
|
*
|
|
23
30
|
* Self-dogfooding guardrails (NON-NEGOTIABLE, P5 spec §B.7):
|
|
24
31
|
* - **Default OFF.** Mutation + egress require `opts.execute === true`. Without
|
|
@@ -30,8 +37,12 @@
|
|
|
30
37
|
* - **Budget caps** (in-code): `maxTokens` / `maxUsd` / `maxPrs = 1` /
|
|
31
38
|
* `maxWorktrees = 1`, checked PRE-FLIGHT before each costed step. `MemoryMax=32G`
|
|
32
39
|
* is an operational launch-wrapper, not an in-code cap.
|
|
33
|
-
* - **
|
|
34
|
-
*
|
|
40
|
+
* - **Fix-gen is GATED + DRAFT-PR-ONLY (T11975).** The autonomous fix-generation
|
|
41
|
+
* stage runs ONLY behind BOTH `execute` AND `CLEO_PI_RUNNER_ENABLED=1` (the
|
|
42
|
+
* same gates guarding the rest of the loop). It produces a candidate patch via
|
|
43
|
+
* the E9 LLM chokepoint and lets the EXISTING egress open a DRAFT PR — NEVER
|
|
44
|
+
* an auto-merge, NEVER an end-user mode, NEVER a `main` push. A failed or empty
|
|
45
|
+
* fix-gen degrades to "no patch" and the egress simply skips the PR.
|
|
35
46
|
*
|
|
36
47
|
* CORE-first: this engine lives in `core` and owns the `ReplayDispatch` port TYPE;
|
|
37
48
|
* the cleo dispatch handler supplies the concrete adapter (dependency inversion —
|
|
@@ -49,6 +60,7 @@ import { CircuitBreaker, DEFAULT_BUDGET, resolveBudget, } from './budget.js';
|
|
|
49
60
|
import { createDhqAdapter } from './dhq-adapter.js';
|
|
50
61
|
import { openDraftPr } from './draft-pr.js';
|
|
51
62
|
import { computeQuestionHash, diffEnvelopes } from './envelope-diff.js';
|
|
63
|
+
import { createLlmFixGenerator, fixPatchPath, generateFixPatch, } from './fix-gen.js';
|
|
52
64
|
import { replayScenario } from './replay.js';
|
|
53
65
|
import { loadScenario } from './scenario.js';
|
|
54
66
|
/**
|
|
@@ -99,6 +111,7 @@ export async function runSelfImprove(opts) {
|
|
|
99
111
|
regressions,
|
|
100
112
|
questionHash,
|
|
101
113
|
draftPr: null,
|
|
114
|
+
fixGen: null,
|
|
102
115
|
breaker: breaker.state,
|
|
103
116
|
});
|
|
104
117
|
// ── 1. boot ONE sandbox (counts against maxWorktrees=1) ─────────────────────
|
|
@@ -133,6 +146,7 @@ export async function runSelfImprove(opts) {
|
|
|
133
146
|
regressions: [],
|
|
134
147
|
questionHash: null,
|
|
135
148
|
draftPr: null,
|
|
149
|
+
fixGen: null,
|
|
136
150
|
breaker: breaker.state,
|
|
137
151
|
};
|
|
138
152
|
}
|
|
@@ -154,16 +168,19 @@ export async function runSelfImprove(opts) {
|
|
|
154
168
|
regressions: diff.regressions,
|
|
155
169
|
questionHash,
|
|
156
170
|
draftPr: null,
|
|
171
|
+
fixGen: null,
|
|
157
172
|
breaker: breaker.state,
|
|
158
173
|
};
|
|
159
174
|
}
|
|
160
175
|
// ── 4. emit ONE leased DHQ (require-mode lease throw ⇒ breaker trip) ────────
|
|
176
|
+
const dhqId = `DHQ-${questionHash.slice(0, 8)}`;
|
|
177
|
+
const dhqTitle = `selfimprove regression in '${opts.scenario}' (${diff.regressions.length} path(s))`;
|
|
161
178
|
try {
|
|
162
179
|
await adapter.upsertOpenDhq({
|
|
163
|
-
dhqId
|
|
180
|
+
dhqId,
|
|
164
181
|
scenario: opts.scenario,
|
|
165
182
|
questionHash,
|
|
166
|
-
title:
|
|
183
|
+
title: dhqTitle,
|
|
167
184
|
regressionJson: JSON.stringify(diff),
|
|
168
185
|
severity: null,
|
|
169
186
|
runId,
|
|
@@ -172,17 +189,65 @@ export async function runSelfImprove(opts) {
|
|
|
172
189
|
catch (err) {
|
|
173
190
|
return tripFromError(breaker, err, logger, opts.scenario, runId, execute, diff.regressions, questionHash);
|
|
174
191
|
}
|
|
192
|
+
// ── 4b. AUTONOMOUS FIX-GENERATION (T11975) — gated, DRAFT-PR-ONLY ───────────
|
|
193
|
+
// Runs ONLY behind BOTH `execute` AND the Pi-runner gate. Produces a candidate
|
|
194
|
+
// unified-diff patch via the E9 LLM chokepoint at the exact path the egress
|
|
195
|
+
// below `existsSync`-checks. Degrades gracefully (no patch ⇒ the egress guard
|
|
196
|
+
// skips the PR) and NEVER throws a rogue mutation. The outcome is folded back
|
|
197
|
+
// onto the DHQ row (refresh-UPSERT — same leased, idempotent path).
|
|
198
|
+
const piRunnerEnabled = opts.piRunnerEnabled ?? process.env.CLEO_PI_RUNNER_ENABLED === '1';
|
|
199
|
+
let fixGen = null;
|
|
200
|
+
if (piRunnerEnabled) {
|
|
201
|
+
const generator = opts.fixGenerator ?? createLlmFixGenerator({ projectRoot: workspaceRoot });
|
|
202
|
+
fixGen = await generateFixPatch({
|
|
203
|
+
request: {
|
|
204
|
+
dhqId,
|
|
205
|
+
scenario: opts.scenario,
|
|
206
|
+
questionHash,
|
|
207
|
+
regressions: diff.regressions,
|
|
208
|
+
repoContext: {
|
|
209
|
+
projectRoot: workspaceRoot,
|
|
210
|
+
summary: loaded.scenario.description,
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
generator,
|
|
214
|
+
...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}),
|
|
215
|
+
logger,
|
|
216
|
+
});
|
|
217
|
+
// Record the fix-gen outcome back onto the open DHQ row (leased, idempotent).
|
|
218
|
+
// A throw here trips the breaker exactly like the initial emit (lease-denial).
|
|
219
|
+
try {
|
|
220
|
+
await adapter.upsertOpenDhq({
|
|
221
|
+
dhqId,
|
|
222
|
+
scenario: opts.scenario,
|
|
223
|
+
questionHash,
|
|
224
|
+
title: dhqTitle,
|
|
225
|
+
regressionJson: JSON.stringify({ diff, fixGen }),
|
|
226
|
+
severity: null,
|
|
227
|
+
runId,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
return tripFromError(breaker, err, logger, opts.scenario, runId, execute, diff.regressions, questionHash);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
logger.info({ scenario: opts.scenario, runId }, 'self-improve fix-gen SKIPPED (CLEO_PI_RUNNER_ENABLED!=1) — DHQ emitted, no patch generated');
|
|
236
|
+
}
|
|
175
237
|
// ── 5. open ONE DRAFT PR (counts against maxPrs=1) + record url back ────────
|
|
176
238
|
let draftPr = null;
|
|
177
239
|
try {
|
|
178
240
|
breaker.chargeOrTrip({ prs: 1 });
|
|
179
241
|
draftPr = await openDraftPr({
|
|
180
242
|
scenario: opts.scenario,
|
|
181
|
-
|
|
243
|
+
// SAME path fix-gen writes to (sanitized, resolved against cwd) so the
|
|
244
|
+
// egress `existsSync` guard finds exactly the file 4b produced.
|
|
245
|
+
diffPath: fixPatchPath(opts.scenario, opts.cwd),
|
|
182
246
|
title: `fix(selfimprove): ${opts.scenario} regression`,
|
|
183
247
|
body: `Auto-detected regression in the \`${opts.scenario}\` dogfood scenario (run ${runId}).`,
|
|
184
248
|
execute,
|
|
185
249
|
...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}),
|
|
250
|
+
...(opts.draftPrRun !== undefined ? { run: opts.draftPrRun } : {}),
|
|
186
251
|
});
|
|
187
252
|
if (draftPr.kind === 'ok') {
|
|
188
253
|
await adapter.recordPrUrl(questionHash, draftPr.prUrl);
|
|
@@ -199,6 +264,7 @@ export async function runSelfImprove(opts) {
|
|
|
199
264
|
regressions: diff.regressions,
|
|
200
265
|
questionHash,
|
|
201
266
|
draftPr,
|
|
267
|
+
fixGen,
|
|
202
268
|
breaker: breaker.state,
|
|
203
269
|
};
|
|
204
270
|
}
|
|
@@ -233,6 +299,7 @@ function tripFromError(breaker, err, logger, scenario, runId, executed, regressi
|
|
|
233
299
|
regressions,
|
|
234
300
|
questionHash,
|
|
235
301
|
draftPr: null,
|
|
302
|
+
fixGen: null,
|
|
236
303
|
breaker: breaker.state,
|
|
237
304
|
};
|
|
238
305
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-loop.js","sourceRoot":"","sources":["../../src/selfimprove/run-loop.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"run-loop.js","sourceRoot":"","sources":["../../src/selfimprove/run-loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "seeded-code-regression",
|
|
3
|
+
"envelopes": [
|
|
4
|
+
{
|
|
5
|
+
"success": true,
|
|
6
|
+
"meta": {
|
|
7
|
+
"gateway": "query",
|
|
8
|
+
"domain": "selfimprove",
|
|
9
|
+
"operation": "probe",
|
|
10
|
+
"source": "rpc"
|
|
11
|
+
},
|
|
12
|
+
"data": {
|
|
13
|
+
"probe": "ok",
|
|
14
|
+
"version": 1
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "seeded-code-regression",
|
|
3
|
+
"description": "Seeded code-regression scenario for end-to-end fix-gen proof (T11988). A deliberately broken selfimprove helper returns the wrong value; the regression is detectable from the replay envelope and fixable by a targeted one-line code patch.",
|
|
4
|
+
"ops": [
|
|
5
|
+
{
|
|
6
|
+
"gateway": "query",
|
|
7
|
+
"domain": "selfimprove",
|
|
8
|
+
"operation": "probe",
|
|
9
|
+
"params": { "scenario": "seeded-code-regression" }
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -183,8 +183,17 @@ export declare function runDuplicateEpicDetection(): Promise<DuplicateEpicResult
|
|
|
183
183
|
* `packages/core/src/spawn/branch-lock.ts` so there is zero duplication
|
|
184
184
|
* of the worktree-management logic (DRY).
|
|
185
185
|
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
186
|
+
* Preserve set (T11996 Amendment 1 — PREDICATE BLOCKER fix):
|
|
187
|
+
* Any task whose status is NOT terminal (i.e. not `done`, `cancelled`, or
|
|
188
|
+
* `archived`) must be preserved. Querying only `status: 'active'` was the
|
|
189
|
+
* original bug — it silently removed worktrees for `pending`, `blocked`, and
|
|
190
|
+
* `proposed` tasks. We now query all non-terminal statuses and build the
|
|
191
|
+
* preserve set from their union.
|
|
192
|
+
*
|
|
193
|
+
* Fail-closed (T11996 Amendment 2):
|
|
194
|
+
* If the task store is unreadable for a project, skip pruning for that
|
|
195
|
+
* project and write a structured audit warning. If ALL projects fail to
|
|
196
|
+
* load tasks, return with zero pruning.
|
|
188
197
|
*
|
|
189
198
|
* Never throws.
|
|
190
199
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cross-project-hygiene.d.ts","sourceRoot":"","sources":["../../src/sentient/cross-project-hygiene.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cross-project-hygiene.d.ts","sourceRoot":"","sources":["../../src/sentient/cross-project-hygiene.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
* @epic T1627
|
|
34
34
|
*/
|
|
35
35
|
import { createHash, randomUUID } from 'node:crypto';
|
|
36
|
-
import { existsSync } from 'node:fs';
|
|
36
|
+
import { appendFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
37
37
|
import { appendFile, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
38
38
|
import { join } from 'node:path';
|
|
39
39
|
import { getLogger } from '../logger.js';
|
|
@@ -426,8 +426,17 @@ export async function runDuplicateEpicDetection() {
|
|
|
426
426
|
* `packages/core/src/spawn/branch-lock.ts` so there is zero duplication
|
|
427
427
|
* of the worktree-management logic (DRY).
|
|
428
428
|
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
429
|
+
* Preserve set (T11996 Amendment 1 — PREDICATE BLOCKER fix):
|
|
430
|
+
* Any task whose status is NOT terminal (i.e. not `done`, `cancelled`, or
|
|
431
|
+
* `archived`) must be preserved. Querying only `status: 'active'` was the
|
|
432
|
+
* original bug — it silently removed worktrees for `pending`, `blocked`, and
|
|
433
|
+
* `proposed` tasks. We now query all non-terminal statuses and build the
|
|
434
|
+
* preserve set from their union.
|
|
435
|
+
*
|
|
436
|
+
* Fail-closed (T11996 Amendment 2):
|
|
437
|
+
* If the task store is unreadable for a project, skip pruning for that
|
|
438
|
+
* project and write a structured audit warning. If ALL projects fail to
|
|
439
|
+
* load tasks, return with zero pruning.
|
|
431
440
|
*
|
|
432
441
|
* Never throws.
|
|
433
442
|
*/
|
|
@@ -450,19 +459,73 @@ export async function runWorktreePrune() {
|
|
|
450
459
|
continue;
|
|
451
460
|
projectsScanned++;
|
|
452
461
|
try {
|
|
453
|
-
//
|
|
454
|
-
|
|
462
|
+
// T11996 Amendment 1: build preserve set from ALL non-terminal statuses.
|
|
463
|
+
// A task is non-terminal if its status is not in TERMINAL_TASK_STATUSES
|
|
464
|
+
// (done / cancelled / archived). Pending, active, blocked, and proposed
|
|
465
|
+
// tasks must NEVER have their worktrees auto-removed or quarantined.
|
|
466
|
+
const preserveTaskIds = new Set();
|
|
467
|
+
let taskStoreReadable = false;
|
|
455
468
|
try {
|
|
456
469
|
const accessor = await getTaskAccessor(proj.path);
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
470
|
+
// Query each non-terminal status and union the results.
|
|
471
|
+
const nonTerminalStatuses = ['pending', 'active', 'blocked', 'proposed'];
|
|
472
|
+
for (const status of nonTerminalStatuses) {
|
|
473
|
+
const { tasks } = await accessor.queryTasks({ status });
|
|
474
|
+
for (const t of tasks)
|
|
475
|
+
preserveTaskIds.add(t.id);
|
|
476
|
+
}
|
|
477
|
+
taskStoreReadable = true;
|
|
460
478
|
}
|
|
461
479
|
catch {
|
|
462
|
-
//
|
|
480
|
+
// T11996 Amendment 2: task store unreadable — skip this project.
|
|
481
|
+
// Write a structured audit warning (no desktop output, ZERO notifications).
|
|
482
|
+
try {
|
|
483
|
+
const auditDir = join(proj.path, '.cleo', 'audit');
|
|
484
|
+
mkdirSync(auditDir, { recursive: true });
|
|
485
|
+
const auditPath = join(auditDir, 'worktree-lifecycle.jsonl');
|
|
486
|
+
const entry = JSON.stringify({
|
|
487
|
+
ts: new Date().toISOString(),
|
|
488
|
+
action: 'prune-skip-fail-closed',
|
|
489
|
+
projectPath: proj.path,
|
|
490
|
+
reason: 'task store unreadable — skipping worktree prune to prevent data loss (T11996 fail-closed)',
|
|
491
|
+
agentId: process.env['CLEO_AGENT_ID'] ?? 'cleo',
|
|
492
|
+
});
|
|
493
|
+
appendFileSync(auditPath, `${entry}\n`, { encoding: 'utf-8' });
|
|
494
|
+
}
|
|
495
|
+
catch {
|
|
496
|
+
// audit is best-effort
|
|
497
|
+
}
|
|
498
|
+
log.warn({ projectPath: proj.path }, `${LOG}: step4 — task store unreadable, skipping project`);
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
if (!taskStoreReadable)
|
|
502
|
+
continue;
|
|
503
|
+
// T11996 Amendment 2: fail-closed — if the preserve set is empty while
|
|
504
|
+
// worktrees may exist, skip to prevent mass-deletion.
|
|
505
|
+
// NOTE: pruneOrphanedWorktrees (branch-lock.ts) calls pruneWorktrees
|
|
506
|
+
// (worktree-prune.ts) which has its own fail-closed guard; this is an
|
|
507
|
+
// additional layer at the hygiene-loop level so we can log the skip here.
|
|
508
|
+
if (preserveTaskIds.size === 0) {
|
|
509
|
+
log.warn({ projectPath: proj.path }, `${LOG}: step4 — preserve set empty, skipping project (fail-closed)`);
|
|
510
|
+
try {
|
|
511
|
+
const auditDir = join(proj.path, '.cleo', 'audit');
|
|
512
|
+
mkdirSync(auditDir, { recursive: true });
|
|
513
|
+
const auditPath = join(auditDir, 'worktree-lifecycle.jsonl');
|
|
514
|
+
const entry = JSON.stringify({
|
|
515
|
+
ts: new Date().toISOString(),
|
|
516
|
+
action: 'prune-skip-fail-closed',
|
|
517
|
+
projectPath: proj.path,
|
|
518
|
+
reason: 'preserve set empty — skipping worktree prune to prevent mass-deletion (T11996 fail-closed)',
|
|
519
|
+
agentId: process.env['CLEO_AGENT_ID'] ?? 'cleo',
|
|
520
|
+
});
|
|
521
|
+
appendFileSync(auditPath, `${entry}\n`, { encoding: 'utf-8' });
|
|
522
|
+
}
|
|
523
|
+
catch {
|
|
524
|
+
// audit is best-effort
|
|
525
|
+
}
|
|
463
526
|
continue;
|
|
464
527
|
}
|
|
465
|
-
const pruneResult = pruneOrphanedWorktrees(proj.path,
|
|
528
|
+
const pruneResult = pruneOrphanedWorktrees(proj.path, preserveTaskIds);
|
|
466
529
|
totalPruned += pruneResult.removed;
|
|
467
530
|
for (const e of pruneResult.errors) {
|
|
468
531
|
errors.push({ projectPath: proj.path, reason: `${e.path}: ${e.reason}` });
|