blitzstrike 1.0.53 → 1.0.54
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 +16 -0
- package/dist/index.js +57 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ 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.54] — 2026-09-13
|
|
9
|
+
|
|
10
|
+
### Added — Autonomous Security Engine (phase 14: budget controller)
|
|
11
|
+
|
|
12
|
+
- **Budget Controller** (`src/mission/budget.ts`, §22):
|
|
13
|
+
- `budgetStatus()` — tracks time / tasks / requests / tokens / cost with
|
|
14
|
+
per-dimension overrun flags.
|
|
15
|
+
- `budgetOverrun()` — detects overruns and returns a specific reason
|
|
16
|
+
(e.g. `budget overrun: tasks, requests`).
|
|
17
|
+
- `consumeTasks()` / `consumeTokens()` — increment consumption counters.
|
|
18
|
+
- `perTaskOverrun()` — enforces the per-task request budget.
|
|
19
|
+
- Extended the `Budget` type with `max_tokens`, `max_cost_usd`,
|
|
20
|
+
`per_task_budget`, `started_at`, and `used_tokens`/`used_cost_usd`.
|
|
21
|
+
- Mission Control now terminates gracefully on ANY budget dimension overrun
|
|
22
|
+
(not just tasks) and records a final budget snapshot in the decision log.
|
|
23
|
+
|
|
8
24
|
## [1.0.53] — 2026-09-13
|
|
9
25
|
|
|
10
26
|
### Added — Autonomous Security Engine (phase 13: model router)
|
package/dist/index.js
CHANGED
|
@@ -18097,10 +18097,16 @@ function newMission(id, target, scope, mode, budget) {
|
|
|
18097
18097
|
max_time_seconds: 3600,
|
|
18098
18098
|
max_tasks: 200,
|
|
18099
18099
|
max_requests: 1000,
|
|
18100
|
+
max_tokens: 2000000,
|
|
18101
|
+
max_cost_usd: 5,
|
|
18100
18102
|
max_parallel_workers: 4,
|
|
18101
18103
|
risk: "medium",
|
|
18104
|
+
per_task_budget: { max_time_seconds: 60, max_requests: 50 },
|
|
18105
|
+
started_at: Date.now(),
|
|
18102
18106
|
used_tasks: 0,
|
|
18103
18107
|
used_requests: 0,
|
|
18108
|
+
used_tokens: 0,
|
|
18109
|
+
used_cost_usd: 0,
|
|
18104
18110
|
...budget ?? {}
|
|
18105
18111
|
},
|
|
18106
18112
|
discovered_assets: [],
|
|
@@ -19134,6 +19140,48 @@ var init_router = __esm(() => {
|
|
|
19134
19140
|
};
|
|
19135
19141
|
});
|
|
19136
19142
|
|
|
19143
|
+
// src/mission/budget.ts
|
|
19144
|
+
function clampRatio(used, max) {
|
|
19145
|
+
if (max <= 0)
|
|
19146
|
+
return 0;
|
|
19147
|
+
return Math.max(0, Math.min(1, used / max));
|
|
19148
|
+
}
|
|
19149
|
+
function budgetStatus(budget, now = Date.now()) {
|
|
19150
|
+
const elapsed = Math.max(0, (now - budget.started_at) / 1000);
|
|
19151
|
+
const dims = [
|
|
19152
|
+
["time", "time (s)", elapsed, budget.max_time_seconds],
|
|
19153
|
+
["tasks", "tasks", budget.used_tasks, budget.max_tasks],
|
|
19154
|
+
["requests", "requests", budget.used_requests, budget.max_requests],
|
|
19155
|
+
["tokens", "tokens", budget.used_tokens, budget.max_tokens],
|
|
19156
|
+
["cost", "cost (USD)", budget.used_cost_usd, budget.max_cost_usd]
|
|
19157
|
+
];
|
|
19158
|
+
return dims.map(([key, label, used, max]) => ({
|
|
19159
|
+
key,
|
|
19160
|
+
label,
|
|
19161
|
+
used: Number(used.toFixed(2)),
|
|
19162
|
+
max,
|
|
19163
|
+
overrun: used >= max,
|
|
19164
|
+
ratio: clampRatio(used, max)
|
|
19165
|
+
}));
|
|
19166
|
+
}
|
|
19167
|
+
function budgetOverrun(budget, now = Date.now()) {
|
|
19168
|
+
const dims = budgetStatus(budget, now).filter((d) => d.overrun);
|
|
19169
|
+
if (dims.length === 0)
|
|
19170
|
+
return { overrun: false, reason: null, dimensions: [] };
|
|
19171
|
+
return {
|
|
19172
|
+
overrun: true,
|
|
19173
|
+
reason: `budget overrun: ${dims.map((d) => d.key).join(", ")}`,
|
|
19174
|
+
dimensions: dims.map((d) => d.key)
|
|
19175
|
+
};
|
|
19176
|
+
}
|
|
19177
|
+
function consumeTasks(budget, tasks, requests) {
|
|
19178
|
+
return {
|
|
19179
|
+
...budget,
|
|
19180
|
+
used_tasks: budget.used_tasks + tasks,
|
|
19181
|
+
used_requests: budget.used_requests + requests
|
|
19182
|
+
};
|
|
19183
|
+
}
|
|
19184
|
+
|
|
19137
19185
|
// src/mission/control.ts
|
|
19138
19186
|
import { existsSync as existsSync8, statSync as statSync4 } from "node:fs";
|
|
19139
19187
|
function scopeAllowed(mission) {
|
|
@@ -19204,7 +19252,10 @@ async function executeTask(task, mission, scope) {
|
|
|
19204
19252
|
}
|
|
19205
19253
|
}
|
|
19206
19254
|
function budgetExhausted(mission) {
|
|
19207
|
-
return mission.budget.
|
|
19255
|
+
return budgetOverrun(mission.budget).overrun;
|
|
19256
|
+
}
|
|
19257
|
+
function budgetReason(mission) {
|
|
19258
|
+
return budgetOverrun(mission.budget).reason ?? "budget_exhausted";
|
|
19208
19259
|
}
|
|
19209
19260
|
async function runMission(mission) {
|
|
19210
19261
|
if (/^https?:\/\//i.test(mission.target) && !scopeAllowed(mission)) {
|
|
@@ -19225,7 +19276,7 @@ async function runMission(mission) {
|
|
|
19225
19276
|
while (iterations < maxIterations) {
|
|
19226
19277
|
iterations += 1;
|
|
19227
19278
|
if (budgetExhausted(m)) {
|
|
19228
|
-
m = { ...m, termination_reason:
|
|
19279
|
+
m = { ...m, termination_reason: budgetReason(m) };
|
|
19229
19280
|
break;
|
|
19230
19281
|
}
|
|
19231
19282
|
const { ready, blocked } = schedule(m.tasks);
|
|
@@ -19286,7 +19337,7 @@ async function runMission(mission) {
|
|
|
19286
19337
|
}
|
|
19287
19338
|
}
|
|
19288
19339
|
}
|
|
19289
|
-
m.budget.
|
|
19340
|
+
m.budget = consumeTasks(m.budget, batch.length, 0);
|
|
19290
19341
|
m = saveMission(m);
|
|
19291
19342
|
}
|
|
19292
19343
|
return finalize2(m);
|
|
@@ -19294,7 +19345,7 @@ async function runMission(mission) {
|
|
|
19294
19345
|
function finalize2(mission) {
|
|
19295
19346
|
let m = mission;
|
|
19296
19347
|
if (budgetExhausted(m)) {
|
|
19297
|
-
m = { ...m, status: "terminated", termination_reason:
|
|
19348
|
+
m = { ...m, status: "terminated", termination_reason: budgetReason(m) };
|
|
19298
19349
|
} else {
|
|
19299
19350
|
m = { ...m, status: "completed", termination_reason: "all tasks resolved" };
|
|
19300
19351
|
}
|
|
@@ -19307,6 +19358,8 @@ function finalize2(mission) {
|
|
|
19307
19358
|
if (mem.saved > 0) {
|
|
19308
19359
|
m = { ...m, memory_refs: [...m.memory_refs, `persisted:${mem.saved} (${mem.deduped} deduped)`] };
|
|
19309
19360
|
}
|
|
19361
|
+
const budgetSummary = budgetStatus(m.budget).map((d) => `${d.key}=${d.used}/${d.max}`).join(", ");
|
|
19362
|
+
m = { ...m, decision_log: [...m.decision_log, { at: new Date().toISOString(), agent: "budget", decision: `final budget: ${budgetSummary}` }] };
|
|
19310
19363
|
return saveMission(m);
|
|
19311
19364
|
}
|
|
19312
19365
|
async function startMission(target, mode, opts = {}) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blitzstrike",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.54",
|
|
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": {
|