blitzstrike 1.0.54 → 1.0.55
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 +15 -0
- package/dist/index.js +63 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ All notable changes to Blitz Strike are documented here.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [1.0.55] — 2026-09-13
|
|
9
|
+
|
|
10
|
+
### Added — Autonomous Security Engine (phase 15: termination engine)
|
|
11
|
+
|
|
12
|
+
- **Termination Engine** (`src/mission/termination.ts`, §24):
|
|
13
|
+
- `evaluateTermination()` — ordered hard stops: user_interrupted →
|
|
14
|
+
budget_exhausted → safety_violation → scope_violation → max_iterations →
|
|
15
|
+
no_progress.
|
|
16
|
+
- `objectiveComplete()` — all tasks in a terminal non-failed state.
|
|
17
|
+
- `applyTermination()` — records the reason + detail into `decision_log` and
|
|
18
|
+
sets `completed`/`terminated`.
|
|
19
|
+
- `NO_PROGRESS_LIMIT` — iterations without progress before declaring stuck.
|
|
20
|
+
- Mission Control now terminates on ANY traceable reason (not just budget) and
|
|
21
|
+
logs the termination decision with detail.
|
|
22
|
+
|
|
8
23
|
## [1.0.54] — 2026-09-13
|
|
9
24
|
|
|
10
25
|
### Added — Autonomous Security Engine (phase 14: budget controller)
|
package/dist/index.js
CHANGED
|
@@ -19182,6 +19182,52 @@ function consumeTasks(budget, tasks, requests) {
|
|
|
19182
19182
|
};
|
|
19183
19183
|
}
|
|
19184
19184
|
|
|
19185
|
+
// src/mission/termination.ts
|
|
19186
|
+
function evaluateTermination(mission, state) {
|
|
19187
|
+
if (state.user_interrupted) {
|
|
19188
|
+
return { terminate: true, reason: "user_interrupted", detail: "user requested stop" };
|
|
19189
|
+
}
|
|
19190
|
+
const overrun = budgetOverrun(mission.budget);
|
|
19191
|
+
if (overrun.overrun) {
|
|
19192
|
+
return { terminate: true, reason: "budget_exhausted", detail: overrun.reason ?? "budget limit" };
|
|
19193
|
+
}
|
|
19194
|
+
if (state.safety_violated) {
|
|
19195
|
+
return { terminate: true, reason: "safety_violation", detail: "a safety invariant was violated" };
|
|
19196
|
+
}
|
|
19197
|
+
if (state.scope_violated) {
|
|
19198
|
+
return { terminate: true, reason: "scope_violation", detail: "an agent attempted to leave scope" };
|
|
19199
|
+
}
|
|
19200
|
+
if (state.iterations >= state.max_iterations) {
|
|
19201
|
+
return { terminate: true, reason: "max_iterations", detail: `reached ${state.max_iterations} iterations` };
|
|
19202
|
+
}
|
|
19203
|
+
if (state.iterations - state.last_progress_iteration >= NO_PROGRESS_LIMIT) {
|
|
19204
|
+
return { terminate: true, reason: "no_progress", detail: `no progress for ${NO_PROGRESS_LIMIT} iterations` };
|
|
19205
|
+
}
|
|
19206
|
+
return { terminate: false, reason: null, detail: "" };
|
|
19207
|
+
}
|
|
19208
|
+
function objectiveComplete(mission) {
|
|
19209
|
+
const done = mission.tasks.every((t) => t.status === "success" || t.status === "skipped" || t.status === "cancelled");
|
|
19210
|
+
if (done && mission.tasks.length > 0) {
|
|
19211
|
+
return { terminate: true, reason: "objective_complete", detail: "all tasks resolved" };
|
|
19212
|
+
}
|
|
19213
|
+
return { terminate: false, reason: null, detail: "" };
|
|
19214
|
+
}
|
|
19215
|
+
function applyTermination(mission, decision) {
|
|
19216
|
+
if (!decision.reason)
|
|
19217
|
+
return mission;
|
|
19218
|
+
return {
|
|
19219
|
+
...mission,
|
|
19220
|
+
status: decision.reason === "objective_complete" ? "completed" : "terminated",
|
|
19221
|
+
termination_reason: decision.reason,
|
|
19222
|
+
decision_log: [
|
|
19223
|
+
...mission.decision_log,
|
|
19224
|
+
{ at: new Date().toISOString(), agent: "termination", decision: `${decision.reason}: ${decision.detail}` }
|
|
19225
|
+
]
|
|
19226
|
+
};
|
|
19227
|
+
}
|
|
19228
|
+
var NO_PROGRESS_LIMIT = 3;
|
|
19229
|
+
var init_termination = () => {};
|
|
19230
|
+
|
|
19185
19231
|
// src/mission/control.ts
|
|
19186
19232
|
import { existsSync as existsSync8, statSync as statSync4 } from "node:fs";
|
|
19187
19233
|
function scopeAllowed(mission) {
|
|
@@ -19251,12 +19297,6 @@ async function executeTask(task, mission, scope) {
|
|
|
19251
19297
|
return { task, ok: false, output: {}, hypotheses: [], graph: { nodes: [], edges: [] }, error: String(e) };
|
|
19252
19298
|
}
|
|
19253
19299
|
}
|
|
19254
|
-
function budgetExhausted(mission) {
|
|
19255
|
-
return budgetOverrun(mission.budget).overrun;
|
|
19256
|
-
}
|
|
19257
|
-
function budgetReason(mission) {
|
|
19258
|
-
return budgetOverrun(mission.budget).reason ?? "budget_exhausted";
|
|
19259
|
-
}
|
|
19260
19300
|
async function runMission(mission) {
|
|
19261
19301
|
if (/^https?:\/\//i.test(mission.target) && !scopeAllowed(mission)) {
|
|
19262
19302
|
return saveMission({ ...mission, status: "terminated", termination_reason: "scope_required" });
|
|
@@ -19272,11 +19312,13 @@ async function runMission(mission) {
|
|
|
19272
19312
|
m = saveMission(m);
|
|
19273
19313
|
const scope = m.scope.join(",");
|
|
19274
19314
|
let iterations = 0;
|
|
19315
|
+
let lastProgress = 0;
|
|
19275
19316
|
const maxIterations = m.budget.max_tasks + 10;
|
|
19276
19317
|
while (iterations < maxIterations) {
|
|
19277
19318
|
iterations += 1;
|
|
19278
|
-
|
|
19279
|
-
|
|
19319
|
+
const hard = evaluateTermination(m, { iterations, max_iterations: maxIterations, last_progress_iteration: lastProgress });
|
|
19320
|
+
if (hard.terminate && hard.reason) {
|
|
19321
|
+
m = applyTermination(m, hard);
|
|
19280
19322
|
break;
|
|
19281
19323
|
}
|
|
19282
19324
|
const { ready, blocked } = schedule(m.tasks);
|
|
@@ -19287,8 +19329,13 @@ async function runMission(mission) {
|
|
|
19287
19329
|
m = saveMission(m);
|
|
19288
19330
|
continue;
|
|
19289
19331
|
}
|
|
19290
|
-
|
|
19291
|
-
|
|
19332
|
+
const done = objectiveComplete(m);
|
|
19333
|
+
if (done.terminate) {
|
|
19334
|
+
m = applyTermination(m, done);
|
|
19335
|
+
} else if (blocked.length > 0) {
|
|
19336
|
+
m = applyTermination(m, { terminate: true, reason: "no_progress", detail: `blocked: ${blocked.length} task(s) with failed dependencies` });
|
|
19337
|
+
} else {
|
|
19338
|
+
m = applyTermination(m, { terminate: true, reason: "objective_complete", detail: "no ready tasks remain" });
|
|
19292
19339
|
}
|
|
19293
19340
|
break;
|
|
19294
19341
|
}
|
|
@@ -19338,16 +19385,17 @@ async function runMission(mission) {
|
|
|
19338
19385
|
}
|
|
19339
19386
|
}
|
|
19340
19387
|
m.budget = consumeTasks(m.budget, batch.length, 0);
|
|
19388
|
+
if (results.some((r) => r.ok))
|
|
19389
|
+
lastProgress = iterations;
|
|
19341
19390
|
m = saveMission(m);
|
|
19342
19391
|
}
|
|
19343
19392
|
return finalize2(m);
|
|
19344
19393
|
}
|
|
19345
19394
|
function finalize2(mission) {
|
|
19346
19395
|
let m = mission;
|
|
19347
|
-
if (
|
|
19348
|
-
|
|
19349
|
-
|
|
19350
|
-
m = { ...m, status: "completed", termination_reason: "all tasks resolved" };
|
|
19396
|
+
if (!m.termination_reason) {
|
|
19397
|
+
const done = objectiveComplete(m);
|
|
19398
|
+
m = done.terminate ? applyTermination(m, done) : applyTermination(m, { terminate: true, reason: "max_iterations", detail: "iteration cap reached" });
|
|
19351
19399
|
}
|
|
19352
19400
|
m.coverage.dimensions = {
|
|
19353
19401
|
...m.coverage.dimensions,
|
|
@@ -19384,6 +19432,7 @@ var init_control = __esm(() => {
|
|
|
19384
19432
|
init_recovery();
|
|
19385
19433
|
init_memory2();
|
|
19386
19434
|
init_router();
|
|
19435
|
+
init_termination();
|
|
19387
19436
|
MODE_PROFILES = {
|
|
19388
19437
|
web: { agents: ["recon", "web", "api", "auth", "validator", "reviewer", "reporter"], verify: true, risk: "medium" },
|
|
19389
19438
|
api: { agents: ["recon", "api", "auth", "validator", "reviewer", "reporter"], verify: true, risk: "medium" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blitzstrike",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.55",
|
|
4
4
|
"description": "Blitz Strike — a universal MCP security-audit toolbelt. BLITZ sweeps the attack surface, EAGLE-EYE traces source-to-sink, STRIKE verifies live. 57 attack chains, 130-tool catalog, intelligence data layer. One server, every agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|