bareloop 0.7.0 → 0.8.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/CHANGELOG.md +283 -0
- package/README.md +4 -2
- package/bareloop.context.md +156 -18
- package/package.json +1 -1
- package/src/exits.js +8 -2
- package/src/job.js +43 -6
- package/src/ledger.js +57 -9
- package/src/plan.js +31 -100
- package/src/planrun.js +318 -62
- package/src/ralph.js +8 -1
- package/src/reuse.js +67 -4
- package/src/run.js +21 -2
- package/src/validate.js +121 -0
- package/types/exits.d.ts +14 -0
- package/types/job.d.ts +13 -2
- package/types/plan.d.ts +23 -38
- package/types/planrun.d.ts +116 -16
- package/types/ralph.d.ts +16 -0
- package/types/reuse.d.ts +5 -1
- package/types/run.d.ts +14 -1
- package/types/validate.d.ts +50 -0
package/types/reuse.d.ts
CHANGED
|
@@ -174,7 +174,11 @@ export function selectBridge({ registry, job, ask, provider, pinned, shortlist,
|
|
|
174
174
|
* **The declared fold, not a re-derivation.** A restarted try's own `try-start`
|
|
175
175
|
* carries the fold it inherited (`priorSpentUsd`/`priorWallMs`), so a resume OF a
|
|
176
176
|
* resume adds only its own new rounds. Re-deriving from the whole file would bill an
|
|
177
|
-
* abandoned attempt twice.
|
|
177
|
+
* abandoned attempt twice. The REPLAN ledger (`priorReplans`/`priorReplanGrantUsed`)
|
|
178
|
+
* folds on this same mechanism and deliberately not on `readGradeSeed`'s: a grade seed
|
|
179
|
+
* feeds a readout, so its documented one-leg-per-resume shortening can only under-claim
|
|
180
|
+
* a direction, while an under-claimed CEILING is a refilled allowance and every kill
|
|
181
|
+
* would buy one (PRD v1.12 — the replan bound is the RUN's).
|
|
178
182
|
*
|
|
179
183
|
* **KNOWN LIMIT, stated rather than discovered later.** A call that was killed BEFORE it
|
|
180
184
|
* returned left no event at all — no `worker-round`, no `selection-result` — so money it
|
package/types/run.d.ts
CHANGED
|
@@ -74,6 +74,15 @@
|
|
|
74
74
|
* chain, not just the leg: without them a leg that re-grades an unchanged tree reports
|
|
75
75
|
* `flat` — "revise the goal" — on a run that was converging when the money ran out.
|
|
76
76
|
* Counts and stage names only; no close bytes cross this seam. Absent is the cold path.
|
|
77
|
+
* @param {{count?: number, grantUsed?: boolean}|null} [opts.resumeReplans] RESUME — the
|
|
78
|
+
* replan LEDGER the chain has already spent (`readResume`'s `restart.replans` /
|
|
79
|
+
* `restart.replanGrantUsed`), forwarded to the plan flow, which seeds its ceiling with
|
|
80
|
+
* it. Its sibling above feeds a READOUT; this one feeds a BOUND, and that is the whole
|
|
81
|
+
* difference: `replanned`/`varianceGrantUsed` are locals in `runPlan`, so without this
|
|
82
|
+
* every kill hands the next leg a fresh allowance of an allowance PRD v1.12 makes the
|
|
83
|
+
* RUN's ("unlimited replanning launders thrash as adaptation"). It also rides onto this
|
|
84
|
+
* run's `job-start` as `priorReplans`, the declared-fold precedent `priorSpentUsd`
|
|
85
|
+
* already sets, so a resume OF a resume folds once. Absent is the cold path.
|
|
77
86
|
* @param {boolean} [opts.layerRoot=false] Layer R (within-run ratchet) — shell
|
|
78
87
|
* territory, threaded to the plan flow. Defaults OFF
|
|
79
88
|
* (decided 2026-07-21): fixation is extinct on every current job (F41), so
|
|
@@ -86,7 +95,7 @@
|
|
|
86
95
|
* 'close-red' | 'close-unsupported' | 'recipe-stale' | 'pricing-red' | 'provider-red' |
|
|
87
96
|
* 'interpreter-red' | 'cap-halt' | 'wall-halt' | 'step-stalled' | `step-red:<id>`
|
|
88
97
|
*/
|
|
89
|
-
export function runJob(rawSpec: object | string, { approvals, workdir, provider, nativeProvider, providerFor, emit, capRuns, strikeLimit, shellCapUsd, closeTimeoutMs, layerRoot, bridge, priorSpentUsd, priorSpendComplete, priorWallMs, resumeSeed, resumeGrades }: {
|
|
98
|
+
export function runJob(rawSpec: object | string, { approvals, workdir, provider, nativeProvider, providerFor, emit, capRuns, strikeLimit, shellCapUsd, closeTimeoutMs, layerRoot, bridge, priorSpentUsd, priorSpendComplete, priorWallMs, resumeSeed, resumeGrades, resumeReplans }: {
|
|
90
99
|
approvals: unknown;
|
|
91
100
|
workdir: string;
|
|
92
101
|
provider: any;
|
|
@@ -111,6 +120,10 @@ export function runJob(rawSpec: object | string, { approvals, workdir, provider,
|
|
|
111
120
|
stage?: string | null;
|
|
112
121
|
value?: number | null;
|
|
113
122
|
}[] | undefined;
|
|
123
|
+
resumeReplans?: {
|
|
124
|
+
count?: number;
|
|
125
|
+
grantUsed?: boolean;
|
|
126
|
+
} | null | undefined;
|
|
114
127
|
layerRoot?: boolean | undefined;
|
|
115
128
|
}): Promise<string>;
|
|
116
129
|
export type Red = {
|
package/types/validate.d.ts
CHANGED
|
@@ -62,4 +62,54 @@ export function redactSecrets(raw: unknown): string;
|
|
|
62
62
|
* @param {(code: string, path: string, detail?: string) => void} red
|
|
63
63
|
*/
|
|
64
64
|
export function sweepSecretLiterals(root: any, red: (code: string, path: string, detail?: string) => void): void;
|
|
65
|
+
/**
|
|
66
|
+
* F49 — a heuristic reject for the catastrophic-backtracking footgun: an
|
|
67
|
+
* unbounded quantifier applied to a group whose body itself repeats unboundedly
|
|
68
|
+
* (`(a+)+`, `(\d*)*`, `([a-z]+){1,}`) — including through a redundant wrapping
|
|
69
|
+
* group (`((a+))+`, `(?:(a+))*`), which is the SAME exponential class as `(a+)+`
|
|
70
|
+
* and is caught by propagating the inner repeat up through the wrapper. Such a
|
|
71
|
+
* pattern can hang `RegExp.test` for seconds on a short crafted body, and THREE
|
|
72
|
+
* fields feed it to an evaluator with NO timeout — one per document:
|
|
73
|
+
* - the AGENT's `artifact-written.pattern`, run by `evalExits` (F49, the
|
|
74
|
+
* original site). Self-DoS only: the agent authors both the pattern and
|
|
75
|
+
* (via the worker) the artifact, so a hang burns only its own run's
|
|
76
|
+
* wall-clock, and there is no arbiter compromise — it cannot escape the
|
|
77
|
+
* fence, forge a green, or leak a secret.
|
|
78
|
+
* - the OPERATOR's `judged.pattern` (`runClose`) and `gapKeep` (`boundGap`),
|
|
79
|
+
* compiled and run against close output in BARELOOP'S OWN PROCESS. These
|
|
80
|
+
* are worse than an operator self-DoS, and the reason is F67's lesson: the
|
|
81
|
+
* regex blocks the MAIN EVENT LOOP, so the in-process stall fuse — a timer
|
|
82
|
+
* in that same loop — cannot fire. The run dies to the OUTSIDE watchdog and
|
|
83
|
+
* is read as a model stall, so a bad regex in a SIGNED spec presents as a
|
|
84
|
+
* provider problem. MEASURED: `boundGap(stream, '(a+)+$')` on a 40-char
|
|
85
|
+
* body does not finish in 20s.
|
|
86
|
+
* So the reject targets the dominant exponential class and fails it as a
|
|
87
|
+
* mechanical gap at the validation gate, before any tokens burn. A full ReDoS
|
|
88
|
+
* analyzer needs a real regex engine (an external native dep we do not take for
|
|
89
|
+
* a LOW issue); exotic overlapping-alternation blowup is out of scope by
|
|
90
|
+
* decision (PARKED to the close-authoring rung — PRD v1.55).
|
|
91
|
+
*
|
|
92
|
+
* SCOPE IS ASYMMETRIC, both directions named on purpose:
|
|
93
|
+
* - false NEGATIVE: overlapping-alternation blowup (`(a|ab)+`-class) is not
|
|
94
|
+
* detected — there is no inner QUANTIFIER to find, so the shape scan cannot
|
|
95
|
+
* see it; the blowup comes from overlapping alternation BRANCHES under a
|
|
96
|
+
* repeat. A genuine limit of the approach, not a bug in it. Widening the
|
|
97
|
+
* detector changes which SIGNED specs are admissible, which is
|
|
98
|
+
* arbiter-adjacent — parked, not chased (PRD v1.55).
|
|
99
|
+
* - false POSITIVE: a group whose repetitions are disambiguated by a literal
|
|
100
|
+
* anchor/delimiter (`(?:^- .+$\n?)+`, `(?:CHANGELOG:.+\n)+`) is FLAGGED even
|
|
101
|
+
* though a real engine runs it linearly — the scan sees the nested-quantifier
|
|
102
|
+
* SHAPE, not the disambiguation. Rejecting it is the FAIL-SAFE direction (it
|
|
103
|
+
* never admits an unsafe pattern), and the cost is bounded: the plan drafter
|
|
104
|
+
* gets a mechanical gap and rewrites (drop the outer `+`, or match once).
|
|
105
|
+
* Detecting "safe because anchored" needs the same real engine we declined,
|
|
106
|
+
* and guessing it wrong would ADMIT an exponential pattern — so the shape
|
|
107
|
+
* reject stands, and the over-rejection is a named, accepted limitation.
|
|
108
|
+
*
|
|
109
|
+
* The input is guaranteed to compile as a RegExp (checked first by the caller),
|
|
110
|
+
* so this scan assumes valid, balanced JS regex syntax.
|
|
111
|
+
* @param {string} src a compiled regex source string
|
|
112
|
+
* @returns {boolean} true iff a nested unbounded quantifier is present
|
|
113
|
+
*/
|
|
114
|
+
export function hasNestedQuantifier(src: string): boolean;
|
|
65
115
|
export const SECRET_PATTERNS: RegExp[];
|