vibeostheog 0.23.37 → 0.23.42

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 CHANGED
@@ -1,3 +1,15 @@
1
+ ## 0.23.42
2
+ Fix paused build followup recovery
3
+ Fix stuck startup plan restore
4
+
5
+
6
+ ## 0.23.40
7
+ - fix: bypass remote selector for manual modes
8
+ - fix: ML pipeline — autoselect unification, branded mode passthrough, vibeultrax/vibeqmax MODE_DELTAS
9
+ - chore: v0.23.38
10
+ fix live thinking mode reset
11
+
12
+
1
13
  ## 0.23.37
2
14
  Fix plan mode agent restore
3
15
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.23.37",
3
+ "version": "0.23.42",
4
4
  "description": "Cost-aware delegation enforcer for OpenCode. Tracks model usage, routes Task subagents to cheaper tiers, surfaces cumulative savings in chat. Includes research audit, reporting framework, project memory, progressive scratchpad decadence, and trinity CLI for brain/medium/cheap slot switching.",
5
5
  "scripts": {
6
6
  "release": "node scripts/release.mjs",
@@ -14,8 +14,8 @@
14
14
  "checkpoint:validate": "node scripts/checkpoint-validate.mjs",
15
15
  "test:scripts": "node --test scripts/tests/checkpoint-validate.test.mjs tests/release-pack.test.mjs",
16
16
  "ts:audit": "node scripts/ts-audit.mjs",
17
- "test": "VIBEOS_MCP_PORT=0 node --test --test-timeout=240000 tests/deep_integration.test.mjs tests/production_regressions.test.mjs tests/release_hardening_tigerteam.test.mjs tests/test_api_migration.neutral.test.mjs tests/test_const_assignment_regression.test.mjs tests/test_delegation_enforcer.test.mjs tests/test_diagnose_cmd.test.mjs tests/test_install_and_recovery.test.mjs tests/test_internals_stress_patterns_offtopic.test.mjs tests/test_saveos_e2e_cleanup.test.mjs tests/test_tdd_enforcer.test.mjs tests/test_10fixes_regression.test.mjs tests/test_cross_session_regression.test.mjs tests/test_mega_all_fixes.test.mjs tests/test_smart_cache_regression.test.mjs src/tests/*.test.js src/utils/tests/*.test.mjs \"src/vibeOS-lib/tests/auto-select-mode.test.mjs\" \"src/vibeOS-lib/tests/blackbox-regression.test.mjs\" \"src/vibeOS-lib/tests/blackbox-smoke.test.mjs\" \"src/vibeOS-lib/tests/budget-first-mode.test.mjs\" \"src/vibeOS-lib/tests/flow-enforcer.test.mjs\" \"src/vibeOS-lib/tests/flow-secrets.test.mjs\" \"src/vibeOS-lib/tests/session-metrics.test.mjs\" \"src/vibeOS-lib/tests/test_stress.test.mjs\" tests/test_trinity_mega_regression.test.mjs tests/test_multisession_mega.test.mjs tests/test_blackbox_default_enabled.test.mjs tests/test_mega_regressions.test.mjs tests/test_footer_alert_regression.test.mjs tests/test_agent_mode_integration.test.mjs tests/test_patterns_telemetry_integration.test.mjs tests/test_footer_dynamic_integration.test.mjs tests/test_ml_pipeline_e2e.test.mjs tests/test_vibeultrax_pipeline_integration.test.mjs tests/test_cv_ml_integration.test.mjs src/lib/hooks/tests/chat-transform-cv-gate.test.js src/lib/hooks/tests/sync-control-settings.test.mjs",
18
- "test:ci": "VIBEOS_MCP_PORT=0 node --test --test-timeout=120000 tests/production_regressions.test.mjs tests/release_hardening_tigerteam.test.mjs tests/test_const_assignment_regression.test.mjs tests/test_diagnose_cmd.test.mjs tests/test_install_and_recovery.test.mjs tests/test_saveos_e2e_cleanup.test.mjs tests/test_tdd_enforcer.test.mjs tests/test_10fixes_regression.test.mjs tests/test_cross_session_regression.test.mjs tests/test_mega_all_fixes.test.mjs tests/test_smart_cache_regression.test.mjs src/tests/*.test.js src/utils/tests/*.test.mjs \"src/vibeOS-lib/tests/auto-select-mode.test.mjs\" \"src/vibeOS-lib/tests/blackbox-regression.test.mjs\" \"src/vibeOS-lib/tests/blackbox-smoke.test.mjs\" \"src/vibeOS-lib/tests/budget-first-mode.test.mjs\" \"src/vibeOS-lib/tests/flow-enforcer.test.mjs\" \"src/vibeOS-lib/tests/flow-secrets.test.mjs\" \"src/vibeOS-lib/tests/session-metrics.test.mjs\" \"src/vibeOS-lib/tests/test_stress.test.mjs\" tests/test_blackbox_default_enabled.test.mjs tests/test_mega_regressions.test.mjs tests/test_delegation_enforcer.test.mjs tests/test_first_install_autoconfig.mjs tests/deep_integration.test.mjs tests/e2e_workflows.test.mjs tests/integration_cross_module.test.mjs tests/privacy_telemetry.test.mjs tests/release-pack.test.mjs tests/test_api_migration.neutral.test.mjs tests/test_internals_stress_patterns_offtopic.test.mjs tests/test_ml_cache_mega.test.mjs tests/test_mode_brand.test.mjs tests/test_multisession_mega.test.mjs tests/test_trinity_mega_regression.test.mjs tests/test_footer_alert_regression.test.mjs tests/test_agent_mode_integration.test.mjs tests/test_patterns_telemetry_integration.test.mjs tests/test_footer_dynamic_integration.test.mjs tests/test_ml_pipeline_e2e.test.mjs tests/test_vibeultrax_pipeline_integration.test.mjs tests/test_cv_ml_integration.test.mjs src/lib/hooks/tests/chat-transform-cv-gate.test.js src/lib/hooks/tests/sync-control-settings.test.mjs",
17
+ "test": "node scripts/run-test-suite.mjs full",
18
+ "test:ci": "node scripts/run-test-suite.mjs ci",
19
19
  "guard": "bash plugins/vibetheog-guard/scripts/run-guard.sh",
20
20
  "guard:full": "VIBETHEOG_GUARD_FULL=1 bash plugins/vibetheog-guard/scripts/run-guard.sh",
21
21
  "hook:precommit": "bash plugins/vibetheog-guard/hooks/pre-commit.sh",
@@ -120,6 +120,10 @@ export function _lazyRefresh() {
120
120
  if (_creditTimer.unref)
121
121
  _creditTimer.unref();
122
122
  }
123
+ export async function refreshCreditSnapshot() {
124
+ await _snapshot();
125
+ return loadCredit();
126
+ }
123
127
  export function loadCredit() {
124
128
  const pct = _cachedPct();
125
129
  if (pct !== null)
@@ -1,9 +1,9 @@
1
1
  // @ts-nocheck
2
- import { readFileSync, writeFileSync, appendFileSync, existsSync, mkdirSync, rmSync } from "node:fs";
3
- import { join, basename } from "node:path";
2
+ import { readFileSync, writeFileSync, appendFileSync, existsSync, mkdirSync, rmSync, readdirSync, statSync } from "node:fs";
3
+ import { join, dirname, basename } from "node:path";
4
4
  import { createHash } from "node:crypto";
5
5
  import { currentModel, currentProjectFingerprint, currentProjectName, _blackboxEnabled, loadSelection, writeSelection, safeJsonParse, applyDecadence, getSessionScratchpadDir, ensureSessionScratchpadDirs, indexAppend, briefedProjects, getActiveJobForProject, loadTodos, promotedProjectPatterns, detectTechStack, projectFingerprint, SCRATCHPAD_ROOT, TRINITY_OPENCODE_CONFIG, TIERS_FILE, loadGlobalLearning, setCurrentProjectFingerprint, setCurrentProjectName, stableJson, TOOL_NAME_NORMALIZE, _cacheDb, recordCacheSaving, } from "../state.js";
6
- import { applySlot, TRINITY_CHEAP, TRINITY_MEDIUM, cacheSavePer1MInputTokens, } from "../pricing.js";
6
+ import { applySlot, TRINITY_CHEAP, TRINITY_MEDIUM, cacheSavePer1MInputTokens, clearWorkspaceFollowupPauseForSession, } from "../pricing.js";
7
7
  import { scoreStress, classifyTurnSimple, loadOptimizationMode, selectOptimizationModeRemote, computeControlVector, getBlackboxTracker, loadBlackboxState as loadBlackboxStateFromCtx, saveBlackboxState as saveBlackboxStateToCtx, extractLastUserText, isLikelyOffTopic, fetchBlackboxEnrichment, estimateContextBudget, buildControlHistoryEntry, setBlackboxEnabled, } from "../turn-classify.js";
8
8
  import { applyBudgetFirstMode, peekBudgetFirstMode } from "../mode-policy.js";
9
9
  import { BRANDED_MODES, RUNTIME_MODES } from "../mode-router.js";
@@ -19,6 +19,32 @@ const BYTES_PER_TOKEN = 4;
19
19
  function getVibeOSHome() {
20
20
  return process.env.VIBEOS_HOME || join(process.env.HOME || "", ".claude");
21
21
  }
22
+ function resolveRestorableOpenCodeAgent(currentSel) {
23
+ const remembered = typeof currentSel?.previous_default_agent === "string" ? currentSel.previous_default_agent.trim() : "";
24
+ if (remembered && remembered !== "plan")
25
+ return remembered;
26
+ try {
27
+ const configDir = dirname(TRINITY_OPENCODE_CONFIG || join(process.env.HOME || "", ".config/opencode/opencode.json"));
28
+ const candidates = readdirSync(configDir)
29
+ .filter((name) => /^opencode\.json\.bak/.test(name))
30
+ .map((name) => {
31
+ const path = join(configDir, name);
32
+ return { path, mtime: statSync(path).mtimeMs };
33
+ })
34
+ .sort((a, b) => b.mtime - a.mtime);
35
+ for (const candidate of candidates) {
36
+ try {
37
+ const snapshot = safeJsonParse(readFileSync(candidate.path, "utf-8"));
38
+ const agent = typeof snapshot?.default_agent === "string" ? snapshot.default_agent.trim() : "";
39
+ if (agent && agent !== "plan")
40
+ return agent;
41
+ }
42
+ catch { }
43
+ }
44
+ }
45
+ catch { }
46
+ return null;
47
+ }
22
48
  function getOpenCodeHome() {
23
49
  return process.env.VIBEOS_OPENCODE_HOME || join(process.env.HOME || "", ".config", "opencode");
24
50
  }
@@ -161,6 +187,12 @@ export function syncControlSettings(cv, options = {}) {
161
187
  return;
162
188
  try {
163
189
  const sid = _OC_SID;
190
+ if (!cv.agent_mode) {
191
+ try {
192
+ clearWorkspaceFollowupPauseForSession(sid);
193
+ }
194
+ catch { }
195
+ }
164
196
  const persistOptimizationMode = options.persistOptimizationMode !== false;
165
197
  const currentSel = loadSelection();
166
198
  const userSetMode = loadSessionOptMode(sid + "_opt");
@@ -204,8 +236,11 @@ export function syncControlSettings(cv, options = {}) {
204
236
  writeIf("tdd_enforce", true);
205
237
  writeIf("tdd_strict", cv.tdd_mode === "strict");
206
238
  }
207
- if (cv.thinking_mode && currentSel.thinking_level !== "full")
208
- writeIf("thinking_level", cv.thinking_mode);
239
+ if (cv.thinking_mode) {
240
+ const nextThinking = cv.thinking_mode === "auto" ? "off" : cv.thinking_mode;
241
+ if (currentSel.thinking_level !== nextThinking)
242
+ writeIf("thinking_level", nextThinking);
243
+ }
209
244
  if (persistOptimizationMode && cv.optimization_mode && userOptMode !== "auto") {
210
245
  if (userOptMode !== cv.optimization_mode) {
211
246
  writeIf("optimization_mode", cv.optimization_mode);
@@ -245,11 +280,13 @@ export function syncControlSettings(cv, options = {}) {
245
280
  const OC_CONFIG = TRINITY_OPENCODE_CONFIG || join(getOpenCodeHome(), "opencode.json");
246
281
  if (existsSync(OC_CONFIG)) {
247
282
  const oc = safeJsonParse(readFileSync(OC_CONFIG, "utf-8"));
248
- const previousAgent = currentSel.previous_default_agent;
249
- if (oc.default_agent === "plan" && previousAgent && previousAgent !== "plan") {
250
- oc.default_agent = previousAgent;
283
+ const restoreAgent = oc.default_agent === "plan" ? resolveRestorableOpenCodeAgent(currentSel) : null;
284
+ if (restoreAgent && oc.default_agent === "plan") {
285
+ oc.default_agent = restoreAgent;
251
286
  writeFileSync(OC_CONFIG, JSON.stringify(oc, null, 2) + "\n");
252
- writeSelection("previous_default_agent", null);
287
+ clearWorkspaceFollowupPauseForSession(sid);
288
+ if (currentSel.previous_default_agent)
289
+ writeSelection("previous_default_agent", null);
253
290
  }
254
291
  }
255
292
  }
@@ -7,6 +7,7 @@ import { classify, modelCostPerTurn, isModelFree, detectContext7, isDocsTarget,
7
7
  import { latestUserIntent } from "./chat-transform.js";
8
8
  import { loadSessionOptMode } from "../selection-manager.js";
9
9
  import { loadOptimizationMode } from "../turn-classify.js";
10
+ import { loadCredit, refreshCreditSnapshot } from "../credit-api.js";
10
11
  function modeCapitalized(mode) {
11
12
  if (!mode)
12
13
  return "Budget";
@@ -14,7 +15,6 @@ function modeCapitalized(mode) {
14
15
  }
15
16
  import { scoreStress, extractFirstWordFromArgs, shouldLogWarn, isUserAskingForTests, resolveEnforcementMode, getLearnedExploratoryWords, noteTaskRoutingLearning, incrementTurnCounter, } from "../turn-classify.js";
16
17
  import { saveReport } from "../reporting.js";
17
- import { loadCredit } from "../credit-api.js";
18
18
  import { remoteCall, VIBEOS_API_ENABLED } from "../api-client.js";
19
19
  import { getCostAnomalyDetector } from "../cost-anomaly.js";
20
20
  import { checkFlowRules } from "../../vibeOS-lib/flow-enforcer.js";
@@ -336,7 +336,15 @@ export const onToolExecuteBefore = async (input, output) => {
336
336
  }
337
337
  }
338
338
  // Credit < 40% + Task: force to cheap slot (mirrors CC's rwh path).
339
- const _credit = loadCredit();
339
+ let _credit = loadCredit();
340
+ if (_credit < 40) {
341
+ try {
342
+ const refreshed = await refreshCreditSnapshot();
343
+ if (Number.isFinite(refreshed))
344
+ _credit = refreshed;
345
+ }
346
+ catch { }
347
+ }
340
348
  if (_credit < 40 && t === "task" && TRINITY_CHEAP && args && typeof args === "object") {
341
349
  if (args.model !== TRINITY_CHEAP) {
342
350
  args.model = TRINITY_CHEAP;
@@ -370,6 +378,10 @@ export const onToolExecuteBefore = async (input, output) => {
370
378
  const apiRoute = await remoteCall("routeModel", [_prompt, currentTier, TRINITY_CHEAP, TRINITY_MEDIUM, LEARNED_EXPLORATORY, stressScore], null);
371
379
  if (apiRoute?.target) {
372
380
  _target = apiRoute.target;
381
+ if (currentTier === "high" && !_exploratoryTarget && TRINITY_MEDIUM && _target === TRINITY_CHEAP) {
382
+ _target = TRINITY_MEDIUM;
383
+ console.error(`[vibeOS] 🔀 Task floor: preserving medium tier for high-tier brain task`);
384
+ }
373
385
  }
374
386
  else if (_target === TRINITY_CHEAP && TRINITY_MEDIUM) {
375
387
  if (stressScore > 0.5) {
@@ -2,12 +2,12 @@ import { BLACKBOX_STATE_FILE, _OC_SID, loadBlackboxState, saveBlackboxState, wit
2
2
  const BASELINE_MODE = "budget";
3
3
  const LOOP_REGIMES = new Set(["LOOPING", "DIVERGENT"]);
4
4
  const QUALITY_REGIMES = new Set(["CONVERGING", "CLOSED"]);
5
- const MANUAL_MODES = new Set(["balanced", "quality", "speed", "longrun"]);
5
+ const MANUAL_MODES = new Set(["balanced", "quality", "speed", "longrun", "vibemax", "vibeqmax", "vibeultrax"]);
6
6
  function normalizeMode(mode) {
7
7
  const normalized = String(mode || BASELINE_MODE).toLowerCase();
8
8
  if (normalized === "auto" || normalized === "")
9
9
  return BASELINE_MODE;
10
- if (normalized === "budget" || normalized === "quality" || normalized === "speed" || normalized === "longrun" || normalized === "balanced") {
10
+ if (normalized === "budget" || normalized === "quality" || normalized === "speed" || normalized === "longrun" || normalized === "balanced" || normalized === "vibemax" || normalized === "vibeqmax" || normalized === "vibeultrax") {
11
11
  return normalized;
12
12
  }
13
13
  return BASELINE_MODE;
@@ -84,20 +84,28 @@ function persistSessionPolicy(state, session, policy, mode) {
84
84
  }
85
85
  export function peekBudgetFirstMode(input = {}) {
86
86
  const requestedMode = normalizeMode(input.requestedMode);
87
+ if (isManualOverride(requestedMode)) {
88
+ return {
89
+ active: false,
90
+ mode: requestedMode,
91
+ reason: "manual",
92
+ shouldPersistRequestedMode: true,
93
+ };
94
+ }
87
95
  const { policy } = loadSessionPolicy();
88
96
  if (policy.active && policy.active_mode && normalizeMode(policy.active_mode) !== BASELINE_MODE) {
89
97
  return {
90
98
  active: true,
91
99
  mode: normalizeMode(policy.active_mode),
92
100
  reason: policy.reason || "episode",
93
- shouldPersistRequestedMode: true,
101
+ shouldPersistRequestedMode: false,
94
102
  };
95
103
  }
96
104
  return {
97
105
  active: false,
98
106
  mode: BASELINE_MODE,
99
107
  reason: "budget",
100
- shouldPersistRequestedMode: true,
108
+ shouldPersistRequestedMode: false,
101
109
  };
102
110
  }
103
111
  export function applyBudgetFirstMode(input = {}) {
@@ -18,7 +18,7 @@ import { readFileSync, writeFileSync, appendFileSync, existsSync, mkdirSync, sta
18
18
  import { join, dirname, basename, resolve } from "node:path";
19
19
  import { homedir, tmpdir } from "node:os";
20
20
  import { createHash } from "node:crypto";
21
- import { currentModel, currentTier, setCurrentModel, setCurrentTier, safeJsonParse, HIGH_TIER_RE, MID_TIER_RE, loadTierRegexes, _modelLocked } from "./state.js";
21
+ import { currentModel, currentTier, setCurrentModel, setCurrentTier, safeJsonParse, HIGH_TIER_RE, MID_TIER_RE, loadTierRegexes, _modelLocked, getCurrentSessionId } from "./state.js";
22
22
  export { HIGH_TIER_RE, MID_TIER_RE, loadTierRegexes };
23
23
  const USER_HOME = (() => { try {
24
24
  return homedir();
@@ -996,6 +996,49 @@ function readWorkspaceSessionModel(directory = "") {
996
996
  }
997
997
  return "";
998
998
  }
999
+ export function clearWorkspaceFollowupPauseForSession(sessionId = "") {
1000
+ let changed = false;
1001
+ const sid = String(sessionId || "").trim();
1002
+ const latestSid = String(readLatestOpenCodeSessionId() || "").trim();
1003
+ const candidates = [...new Set([sid, latestSid].filter(Boolean))];
1004
+ if (candidates.length === 0)
1005
+ return false;
1006
+ const roots = [getOpenCodeDesktopHome(), getOpenCodeHome()];
1007
+ for (const root of roots) {
1008
+ try {
1009
+ if (!existsSync(root) || !statSync(root).isDirectory())
1010
+ continue;
1011
+ const files = readdirSync(root)
1012
+ .filter((name) => /^opencode\.workspace\..*\.dat$/i.test(name))
1013
+ .map((name) => join(root, name))
1014
+ .sort((a, b) => statSync(b).mtimeMs - statSync(a).mtimeMs);
1015
+ for (const file of files) {
1016
+ try {
1017
+ const outer = safeJsonParse(readFileSync(file, "utf-8"));
1018
+ const followupRaw = outer?.["workspace:followup"];
1019
+ const followup = typeof followupRaw === "string" ? safeJsonParse(followupRaw) : followupRaw;
1020
+ if (!followup || typeof followup !== "object" || !followup.paused)
1021
+ continue;
1022
+ let touched = false;
1023
+ for (const candidate of candidates) {
1024
+ if (followup.paused[candidate]) {
1025
+ delete followup.paused[candidate];
1026
+ touched = true;
1027
+ }
1028
+ }
1029
+ if (!touched)
1030
+ continue;
1031
+ outer["workspace:followup"] = JSON.stringify(followup);
1032
+ writeFileSync(file, JSON.stringify(outer, null, 2) + "\n");
1033
+ changed = true;
1034
+ }
1035
+ catch { }
1036
+ }
1037
+ }
1038
+ catch { }
1039
+ }
1040
+ return changed;
1041
+ }
999
1042
  function readLatestOpenCodeSessionId(directory = "") {
1000
1043
  try {
1001
1044
  const globalPath = join(getOpenCodeDesktopHome(), "opencode.global.dat");
@@ -1251,6 +1294,7 @@ export function applySlot(slot, projectDir = "") {
1251
1294
  oc.model = ocModel;
1252
1295
  writeFileSync(ocConfig, JSON.stringify(oc, null, 2) + "\n");
1253
1296
  }
1297
+ clearWorkspaceFollowupPauseForSession(getCurrentSessionId());
1254
1298
  _refreshModel(process.cwd());
1255
1299
  return { ok: true, ocModel };
1256
1300
  }
@@ -9,6 +9,7 @@ export { scoreStress, estimateContextBudget, classifyTurnSimple, tokenizeWords,
9
9
  function getVibeOSHome() {
10
10
  return process.env.VIBEOS_HOME || join(process.env.HOME || "", ".claude");
11
11
  }
12
+ const QUALITY_STRESS_THRESHOLD = 1.5;
12
13
  function autoSelectMode(subRegime, stressMultiplier) {
13
14
  const regime = String(subRegime || "INIT").toUpperCase();
14
15
  const stress = Number(stressMultiplier ?? 0);
@@ -18,25 +19,25 @@ function autoSelectMode(subRegime, stressMultiplier) {
18
19
  return "speed";
19
20
  if (regime === "CONVERGING" || regime === "CLOSED")
20
21
  return "quality";
21
- if (stress > 1.5)
22
+ if (stress > QUALITY_STRESS_THRESHOLD)
22
23
  return "quality";
23
24
  return "budget";
24
25
  }
25
26
  export function resolveOptimizationMode(subRegime, stressMultiplier, optimizationMode) {
26
27
  const normalized = String(optimizationMode || "auto").toLowerCase();
27
- if (!isApiFallback())
28
+ if (normalized === "auto" || normalized === "")
28
29
  return autoSelectMode(subRegime || "INIT", stressMultiplier);
29
- if (normalized === "auto" || normalized === "" || normalized === "vibeultrax" || normalized === "vibeqmax" || normalized === "vibemax")
30
- return autoSelectMode(subRegime || "INIT", stressMultiplier);
31
- if (normalized === "balanced" || normalized === "budget" || normalized === "quality" || normalized === "speed" || normalized === "longrun") {
30
+ if (isApiFallback())
31
+ return "budget";
32
+ if (normalized === "balanced" || normalized === "budget" || normalized === "quality" || normalized === "speed" || normalized === "longrun" || normalized === "audit" || normalized === "forensic" || normalized === "vibeultrax" || normalized === "vibeqmax" || normalized === "vibemax") {
32
33
  return normalized;
33
34
  }
34
35
  return "budget";
35
36
  }
36
37
  export function resolveOptimizationSlot(mode) {
37
38
  const normalized = String(mode || "budget").toLowerCase();
38
- return normalized === "speed" ? "medium"
39
- : normalized === "quality" || normalized === "longrun" ? "brain"
39
+ return normalized === "speed" || normalized === "vibemax" ? "medium"
40
+ : normalized === "quality" || normalized === "longrun" || normalized === "vibeultrax" || normalized === "vibeqmax" ? "brain"
40
41
  : "cheap";
41
42
  }
42
43
  export function bootstrapOptimizationSession() {
@@ -69,18 +70,19 @@ export function bootstrapOptimizationSession() {
69
70
  return { mode: resolvedMode, slot: resolvedSlot };
70
71
  }
71
72
  export async function selectOptimizationModeRemote(subRegime, stressMultiplier, fallbackMode) {
73
+ const normalizedRequestedMode = String(fallbackMode || "auto").toLowerCase();
72
74
  const fallback = resolveOptimizationMode(subRegime, stressMultiplier, fallbackMode);
73
- if (!isApiFallback())
74
- return autoSelectMode(subRegime || "INIT", stressMultiplier);
75
+ if (normalizedRequestedMode !== "auto" && normalizedRequestedMode !== "")
76
+ return fallback;
77
+ if (isApiFallback())
78
+ return fallback;
75
79
  try {
76
- if (!isApiFallback()) {
77
- const client = getApiClient();
78
- if (client) {
79
- const res = await client.blackboxSelectMode(subRegime || "INIT", Number(stressMultiplier ?? 0));
80
- const selected = String(res?.mode || "").toLowerCase();
81
- if (selected === "balanced" || selected === "budget" || selected === "quality" || selected === "speed" || selected === "longrun" || selected === "vibemax") {
82
- return selected;
83
- }
80
+ const client = getApiClient();
81
+ if (client) {
82
+ const res = await client.blackboxSelectMode(subRegime || "INIT", Number(stressMultiplier ?? 0));
83
+ const selected = String(res?.mode || "").toLowerCase();
84
+ if (selected === "balanced" || selected === "budget" || selected === "quality" || selected === "speed" || selected === "longrun" || selected === "audit" || selected === "forensic" || selected === "vibeultrax" || selected === "vibeqmax" || selected === "vibemax") {
85
+ return selected;
84
86
  }
85
87
  }
86
88
  }
@@ -93,7 +95,7 @@ function computeControlVector(_state, _action, _optimizationMode) {
93
95
  const isRelaxed = mode === "budget" || mode === "speed";
94
96
  const subRegime = _state?.sub_regime || "INIT";
95
97
  const stress = Number(_state?.latest_stress_multiplier ?? 0);
96
- const tierBias = stress > 1.5 ? "brain"
98
+ const tierBias = stress > QUALITY_STRESS_THRESHOLD ? "brain"
97
99
  : subRegime === "CONVERGING" || subRegime === "CLOSED" ? "brain"
98
100
  : subRegime === "REFINING" || subRegime === "LOOPING" ? "medium"
99
101
  : mode === "quality" || mode === "longrun" ? "brain"
@@ -112,7 +114,7 @@ function computeControlVector(_state, _action, _optimizationMode) {
112
114
  stress_multiplier: 1.0,
113
115
  context7_urgency: isStrict ? "required" : "preferred",
114
116
  wbp_verbosity: isStrict ? "verbose" : isRelaxed ? "minimal" : "normal",
115
- agent_mode: (subRegime === "REFINING" || subRegime === "CONVERGING" || subRegime === "CLOSED") && stress <= 1.5 ? "plan" : undefined,
117
+ agent_mode: (subRegime === "REFINING" || subRegime === "CONVERGING" || subRegime === "CLOSED") && stress <= QUALITY_STRESS_THRESHOLD ? "plan" : undefined,
116
118
  optimization_mode: mode,
117
119
  directives: [],
118
120
  };
@@ -98,6 +98,7 @@ const REGIME_CONTROL = {
98
98
  },
99
99
  };
100
100
  const DEFAULT_CONTROL = REGIME_CONTROL.EXPLORING;
101
+ const QUALITY_STRESS_THRESHOLD = 1.5;
101
102
  const MODE_DELTAS = {
102
103
  balanced: {},
103
104
  budget: {
@@ -175,13 +176,46 @@ const MODE_DELTAS = {
175
176
  api_enrichment: true,
176
177
  outcome_detection: true,
177
178
  },
179
+ vibeultrax: {
180
+ tier_bias: "brain",
181
+ thinking_mode: "full",
182
+ tdd_mode: "quality",
183
+ tdd_focus: ["full-coverage", "edge-cases", "property-based"],
184
+ flow_mode: "strict",
185
+ flow_focus: ["write-edit-check", "no-untouched-files", "no-lgtm", "suggest-alternative"],
186
+ enforcement_mode: "strict",
187
+ wbp_verbosity: "detailed",
188
+ context7_urgency: "required",
189
+ stress_multiplier: 2.5,
190
+ loop_threshold: 0.3,
191
+ api_enrichment: true,
192
+ outcome_detection: true,
193
+ },
194
+ vibeqmax: {
195
+ tier_bias: "brain",
196
+ thinking_mode: "full",
197
+ tdd_mode: "quality",
198
+ tdd_focus: ["skeleton-on-write", "assertion-check", "edge-cases"],
199
+ flow_mode: "strict",
200
+ flow_focus: ["write-edit-check", "no-lgtm", "check-debug-artifacts"],
201
+ enforcement_mode: "strict",
202
+ wbp_verbosity: "normal",
203
+ context7_urgency: "required",
204
+ stress_multiplier: 1.5,
205
+ loop_threshold: 0.5,
206
+ api_enrichment: true,
207
+ outcome_detection: true,
208
+ },
178
209
  };
179
210
  export function autoSelectMode(subRegime, stressMultiplier) {
180
- if (subRegime === "CONVERGING" || subRegime === "CLOSED")
181
- return "quality";
182
- if (subRegime === "LOOPING")
211
+ const regime = String(subRegime || "INIT").toUpperCase();
212
+ if (regime === "AUDIT" || regime === "FORENSIC")
213
+ return regime.toLowerCase();
214
+ if (regime === "LOOPING")
183
215
  return "speed";
184
- if (stressMultiplier && stressMultiplier > 0.5)
216
+ if (regime === "CONVERGING" || regime === "CLOSED")
217
+ return "quality";
218
+ if (stressMultiplier && stressMultiplier > QUALITY_STRESS_THRESHOLD)
185
219
  return "quality";
186
220
  return "budget";
187
221
  }