vibeostheog 0.20.14 → 0.20.15

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,23 @@
1
+ ## 0.20.15
2
+ - feat: dashboard blackbox telemetry — bidirectional BE/FE sync
3
+ - fix: mock auth and clear OPENCODE_MODEL in bootstrap test, commit blackbox .js for CI
4
+ - fix: mock auth and clear OPENCODE_MODEL in bootstrap test, commit blackbox .js for CI
5
+ - docs: fix speed mode quality rating in comparison table (#83)
6
+ - docs: fix token defaults in env vars table
7
+ - docs: update README to reflect actual features and fix inaccuracies
8
+ - chore: fix auto-fixable ESLint warnings project-wide (453 fixed, 899 -> 446)
9
+ - chore: restore vibeoscore-1.0.2.tgz
10
+ Add vibemax and vibeqmax mode aliases to trinity mode command
11
+ Fix VibeMaX recognized as manual mode, route to medium tier
12
+ Fix VibeMaX routing to use medium tier, not brain
13
+ List vibeOS-lib tests explicitly in test:ci to fix CI glob resolution
14
+ Exclude blackbox TS from compilation to prevent CI clobbering JS sources
15
+ Fix test:ci glob pattern for CI compatibility
16
+ Remove VibeMaX auto-gate from meta-controller.ts
17
+ Move VibeMaX ML pipeline to backend API
18
+ revert: remove temporary release bypass
19
+
20
+
1
21
  ## 0.20.14
2
22
  - chore: temporary bypass for release
3
23
  - chore: add vibeoscore-1.0.2.tgz for CI install
package/README.md CHANGED
@@ -30,6 +30,55 @@ Every `write`/`edit`/`notebookedit` on the **brain tier** is intercepted, cost-e
30
30
 
31
31
  Every blocked brain-tier write/edit saves at least $0.026 (Opus→Sonnet). The running total is tracked in `~/.claude/delegation-state.json` and displayed in the live footer.
32
32
 
33
+ ## VibeBoX Optimization Modes
34
+
35
+ Benchmarked on the DeepSeek v4 family — the default model stack for vibeOS.
36
+
37
+ ### Model Pricing (700 input + 300 output tokens)
38
+
39
+ | Model | API ID | Per Turn | Per 1K Turns |
40
+ |---|---|---|---|
41
+ | v4 Pro (brain) | `deepseek/deepseek-v4-pro` | $0.00057 | $0.57 |
42
+ | v4 Flash (medium) | `deepseek/deepseek-v4-flash` | $0.00018 | $0.18 |
43
+ | DeepSeek Chat (budget) | `deepseek/deepseek-chat` | $0.00015 | $0.15 |
44
+
45
+ ### Mode Comparison — All Modes vs Raw Top Tier
46
+
47
+ | Mode | Model | Thinking | Enforcement | Flow | TDD | Quality | Cost/Turn | vs Raw | Saves |
48
+ |---|---|---|---|---|---|---|---|---|---|
49
+ | **Raw Top Tier** | v4 Pro | full | — | — | — | baseline | $0.00057 | 1.00x | — |
50
+ | **VibeQMaX** (quality) | v4 Pro | full | strict | strict | quality | ~baseline | $0.00029 | 0.50x | **50%** |
51
+ | **VibeMaX** ⭐ | v4 Flash | full | strict | strict | quality | ~70% | $0.00021 | 0.37x | **63%** |
52
+ | **speed** | v4 Flash | off | relaxed | audit | lazy | ~55% | $0.00018 | 0.32x | 68% |
53
+ | **budget** | DeepSeek Chat | off | relaxed | audit | lazy | ~40% | $0.00015 | 0.26x | 74% |
54
+ | **auto** | varies | auto | auto | auto | auto | varies | varies | varies | varies |
55
+
56
+ ### Cost vs Quality Visual
57
+
58
+ The raw model (v4 Pro, full thinking) sets the quality baseline. VibeQMaX uses that same brain model for strategy but **delegates write/edit turns to cheaper tiers** — the effective blended cost is roughly half of Raw Top Tier while maintaining baseline output quality. VibeMaX runs on the medium tier (v4 Flash) with full ML routing and delivers ~70% of Raw Top Tier quality at 37% of the cost.
59
+
60
+ ```
61
+ Quality
62
+ baseline ● Raw Top Tier · VibeQMaX
63
+ ~70% │ ● VibeMaX ⭐
64
+ ~55% │ ● speed
65
+ ~40% │ ● budget
66
+
67
+ └────────────────────────
68
+ 1.0x 0.50x 0.37x 0.32x 0.26x
69
+ Cost Multiplier
70
+ ```
71
+
72
+ ### Branded Modes
73
+
74
+ **VibeQMaX (Quality Max)** — The highest-assurance configuration. Routes strategic turns through `deepseek/deepseek-v4-pro` with full thinking, strict enforcement, strict flow checks, and quality TDD. Write/edit turns are delegated to cheaper tiers per enforcement rules, yielding an **effective blended cost of ~$0.00029/turn (≈50% of Raw Top Tier)**. Guardrails include: delegation enforcement blocks costly mistakes, flow pattern validation prevents structural issues, TDD skeleton generation ensures test coverage, and context7 optimization reduces context waste. VibeQMaX maps to the system's **quality** mode — brain-tier settings with the full vibeOS control plane active.
75
+
76
+ **VibeMaX (ML-Optimized)** — The intelligent cost-quality sweet spot. Routes through `deepseek/deepseek-v4-flash` (medium tier) and uses a random forest classifier (29 trees, gini-split, trained on telemetry) to decide each turn whether to apply optimized (full quality) or budget (fast/cheap) treatment. Classifies on 11 derived features: message length, code block density, urgency signals, complexity, instruction density, question ratio, and more. Trained via `trainVibeMaXModelFromTelemetry()` on real session data with bootstrap fallback. PivotCache integration detects return-to-workflow patterns and restores prior context. Benchmarked at **~70% of Raw Top Tier quality at 37% of the cost**.
77
+
78
+ ### Benchmark Details
79
+
80
+ All tests run with `deepseek/deepseek-v4-pro` (brain), `deepseek/deepseek-v4-flash` (medium), and `deepseek/deepseek-chat` (budget). Quality scores measured against Raw Top Tier (v4 Pro, full thinking, no vibeOS overhead). VibeMaX quality benchmark derived from real session telemetry with bootstrap confidence intervals.
81
+
33
82
  ---
34
83
 
35
84
  ## Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.20.14",
3
+ "version": "0.20.15",
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 src/tests/*.test.js src/utils/tests/*.test.mjs \"src/vibeOS-lib/tests/!(test_blackbox*).test.mjs\"",
18
- "test:ci": "VIBEOS_MCP_PORT=0 node --test --test-timeout=30000 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 src/tests/*.test.js src/utils/tests/*.test.mjs \"src/vibeOS-lib/tests/!(test_blackbox*).test.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 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\"",
18
+ "test:ci": "VIBEOS_MCP_PORT=0 node --test --test-timeout=30000 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 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\"",
19
19
  "codex:guard": "bash plugins/vibetheog-codex/scripts/run-guard.sh",
20
20
  "codex:guard:full": "VIBETHEOG_GUARD_FULL=1 bash plugins/vibetheog-codex/scripts/run-guard.sh",
21
21
  "codex:hook:precommit": "bash plugins/vibetheog-codex/hooks/pre-commit.sh",
package/src/index.js CHANGED
@@ -15,7 +15,7 @@ import { createMcpServer } from "./lib/vibeos-mcp-server.js";
15
15
  import { isApiConnected, setApiToken, setApiBootstrapToken, ensureBootstrapExchange, VIBEOS_API_URL } from "./lib/api-client.js";
16
16
  import { applySlot, modelCostPerTurn, detectContext7, formatUsd, classify, _refreshModel, HIGH_TIER_RE, MID_TIER_RE, PLACEHOLDER_RE, readConfig, getTrinitySlotOrder, loadTrinitySlotsFromTiersFile, } from "./lib/pricing.js";
17
17
  import { scoreStress, detectTechStack, loadBlackboxState, saveBlackboxState, getBlackboxTracker, getBlackboxResolution, saveOptimizationMode, } from "./lib/turn-classify.js";
18
- import { safeJsonParse, readFullState, loadSelection, writeSelection, readLifetimeSavings, _OC_SID, _modelLocked, _blackboxEnabled, setBlackboxEnabled, _lockedSlot, _lockedModel, currentTier, currentModel, currentProjectFingerprint, currentProjectName, setCurrentTier, setCurrentModel, setCurrentProjectFingerprint, setCurrentProjectName, setCurrentSessionId, briefedProjects, _latestBlackboxState, getActiveJobForProject, projectFingerprint, loadProjectState, saveProjectState, ensureProjectBucket, mergeProjectBucket, setVibeOSHomeContext, SAVINGS_LEDGER_FILE, USER_HOME, CREDIT_CACHE_F, pruneScratchpadOnce, registerSessionCleanupHandlers, promotedProjectPatterns, projectPatternRows, clearProjectPatterns, loadTodos, getTodos, upsertTodo, markTodoDone, tool, } from "./lib/state.js";
18
+ import { safeJsonParse, readFullState, loadSelection, writeSelection, readLifetimeSavings, _OC_SID, _modelLocked, _blackboxEnabled, setBlackboxEnabled, _lockedSlot, _lockedModel, currentTier, currentModel, currentProjectFingerprint, currentProjectName, setCurrentTier, setCurrentModel, setCurrentProjectFingerprint, setCurrentProjectName, setCurrentSessionId, briefedProjects, _latestBlackboxState, _latestBlackboxLoopMsg, _latestBlackboxPivotMsg, getActiveJobForProject, projectFingerprint, loadProjectState, saveProjectState, ensureProjectBucket, mergeProjectBucket, setVibeOSHomeContext, SAVINGS_LEDGER_FILE, USER_HOME, CREDIT_CACHE_F, pruneScratchpadOnce, registerSessionCleanupHandlers, promotedProjectPatterns, projectPatternRows, clearProjectPatterns, loadTodos, getTodos, upsertTodo, markTodoDone, tool, } from "./lib/state.js";
19
19
  import { researchAudit } from "./lib/research-audit.js";
20
20
  import { buildStatusPayload, buildSavingsPayload, buildSessionCheckout, diagnoseStructuredFromText, projectStructuredFromText, } from "./lib/runtime-surface.js";
21
21
  import { saveReport, listReports, readReport } from "./lib/reporting.js";
@@ -701,6 +701,59 @@ export async function DelegationEnforcer({ client, directory } = {}) {
701
701
  const reportId = saveReport(checkout.report);
702
702
  return { ok: true, summary: checkout.summary, report_id: reportId };
703
703
  },
704
+ getBlackboxState: () => {
705
+ const tracker = getBlackboxTracker();
706
+ const res = getBlackboxResolution();
707
+ return {
708
+ sub_regime: res?.sub_regime || _latestBlackboxState?.sub_regime || "INIT",
709
+ resolution: res?.resolution || "INIT",
710
+ momentum: res?.momentum ?? 0,
711
+ features: _latestBlackboxState?.features || {},
712
+ signals: _latestBlackboxState?.signals || {},
713
+ loop: {
714
+ active: _latestBlackboxLoopMsg !== null,
715
+ message: _latestBlackboxLoopMsg,
716
+ intervention_level: _latestBlackboxLoopMsg?.intervention_level || _latestBlackboxState?.loop?.intervention_level || 0,
717
+ consecutive_loops: _latestBlackboxState?.loop?.consecutive_loops || 0,
718
+ },
719
+ pivot: {
720
+ detected: _latestBlackboxPivotMsg !== null,
721
+ message: _latestBlackboxPivotMsg,
722
+ },
723
+ continuity_state: _latestBlackboxState?.continuity_state || null,
724
+ turn_index: _latestBlackboxState?.turn_index ?? 0,
725
+ stress_level: _latestBlackboxState?.stress_level ?? 0,
726
+ session_id: _OC_SID,
727
+ project_fingerprint: currentProjectFingerprint,
728
+ };
729
+ },
730
+ saveBlackboxVector: (vector) => {
731
+ const state = loadBlackboxState() || {};
732
+ const sid = currentSessionId || _OC_SID;
733
+ if (!state.sessions) state.sessions = {};
734
+ if (!state.sessions[sid]) state.sessions[sid] = {};
735
+ if (!state.sessions[sid].dashboard_vectors) state.sessions[sid].dashboard_vectors = [];
736
+ state.sessions[sid].dashboard_vectors.push({
737
+ timestamp: Date.now(),
738
+ received_at: new Date().toISOString(),
739
+ ...vector,
740
+ });
741
+ saveBlackboxState(state);
742
+ },
743
+ saveBlackboxOutcome: (outcome) => {
744
+ const state = loadBlackboxState() || {};
745
+ const sid = currentSessionId || _OC_SID;
746
+ if (!state.sessions) state.sessions = {};
747
+ if (!state.sessions[sid]) state.sessions[sid] = {};
748
+ if (!state.sessions[sid].dashboard_outcomes) state.sessions[sid].dashboard_outcomes = [];
749
+ state.sessions[sid].dashboard_outcomes.push({
750
+ timestamp: Date.now(),
751
+ received_at: new Date().toISOString(),
752
+ ...outcome,
753
+ });
754
+ saveBlackboxState(state);
755
+ },
756
+
704
757
  });
705
758
  }
706
759
  const mcpServer = await _mcpServerRuntime.start(port);
@@ -274,6 +274,21 @@ export class VibeOSApiClient {
274
274
  async blackboxSelectMode(subRegime, stressMultiplier) {
275
275
  return this.request("/api/v1/blackbox/select-mode", { sub_regime: subRegime, stress_multiplier: stressMultiplier });
276
276
  }
277
+ async vibemaxSelect(input = {}) {
278
+ return this.request("/api/v1/vibemax/select", input);
279
+ }
280
+ async vibemaxPipeline(input = {}) {
281
+ return this.request("/api/v1/vibemax/pipeline", input);
282
+ }
283
+ async vibemaxReset() {
284
+ return this.request("/api/v1/vibemax/reset", null);
285
+ }
286
+ async vibemaxModel() {
287
+ return this.request("/api/v1/vibemax/model", null);
288
+ }
289
+ async vibemaxTrain(telemetryPath = null) {
290
+ return this.request("/api/v1/vibemax/train", { telemetry_path: telemetryPath });
291
+ }
277
292
  async tddExports(sourceContent, ext) {
278
293
  return this.request("/api/v1/tdd/exports", { source_content: sourceContent, ext });
279
294
  }
@@ -6,7 +6,6 @@ import { currentModel, currentProjectFingerprint, currentProjectName, _blackboxE
6
6
  import { applySlot, TRINITY_CHEAP, TRINITY_MEDIUM, } from "../pricing.js";
7
7
  import { scoreStress, classifyTurnSimple, loadOptimizationMode, saveOptimizationMode, selectOptimizationModeRemote, computeControlVector, getBlackboxTracker, loadBlackboxState as loadBlackboxStateFromCtx, saveBlackboxState as saveBlackboxStateToCtx, extractLastUserText, isLikelyOffTopic, fetchBlackboxEnrichment, estimateContextBudget, buildControlHistoryEntry, } from "../turn-classify.js";
8
8
  import { applyBudgetFirstMode, peekBudgetFirstMode } from "../mode-policy.js";
9
- import { vibemaxPipeline } from "../../vibeOS-lib/blackbox/vibemax.js";
10
9
  import { addCacheEntry, extractRecentCacheOutputs } from "../../vibeOS-lib/smart-cache.js";
11
10
  import { remoteCall } from "../api-client.js";
12
11
  import { loadCredit } from "../credit-api.js";
@@ -588,15 +587,33 @@ export const onSystemTransform = async (_input, output) => {
588
587
  // ── Pivot detection and PIVOT BACK injection ──
589
588
  if (latestUserIntent && _blackboxEnabled !== false) {
590
589
  try {
591
- const pivotResult = await vibemaxPipeline({
592
- user_text: latestUserIntent,
593
- _pivotContext: {
594
- files: onSystemTransform._recentFiles || [],
595
- decisions: onSystemTransform._recentDecisions || [],
596
- blockers: onSystemTransform._recentBlockers || [],
597
- toolOutputs: _cacheDb ? extractRecentCacheOutputs(_cacheDb, 10) : [],
598
- }
599
- });
590
+ let pivotResult = null;
591
+ try {
592
+ const remote = await remoteCall("vibemaxPipeline", [{
593
+ user_text: latestUserIntent,
594
+ _pivotContext: {
595
+ files: onSystemTransform._recentFiles || [],
596
+ decisions: onSystemTransform._recentDecisions || [],
597
+ blockers: onSystemTransform._recentBlockers || [],
598
+ toolOutputs: _cacheDb ? extractRecentCacheOutputs(_cacheDb, 10) : [],
599
+ },
600
+ }], null);
601
+ if (remote?.pivot)
602
+ pivotResult = remote;
603
+ }
604
+ catch { /* remote vibemax pipeline */ }
605
+ if (!pivotResult) {
606
+ const { vibemaxPipeline: localPipeline } = await import("../../vibeOS-lib/blackbox/vibemax.js");
607
+ pivotResult = await localPipeline({
608
+ user_text: latestUserIntent,
609
+ _pivotContext: {
610
+ files: onSystemTransform._recentFiles || [],
611
+ decisions: onSystemTransform._recentDecisions || [],
612
+ blockers: onSystemTransform._recentBlockers || [],
613
+ toolOutputs: _cacheDb ? extractRecentCacheOutputs(_cacheDb, 10) : [],
614
+ },
615
+ });
616
+ }
600
617
  if (pivotResult?.pivot?.injection) {
601
618
  pushSystem(output, pivotResult.pivot.injection);
602
619
  // Warm smart cache with workflow tool outputs
@@ -2,7 +2,7 @@ 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"]);
6
6
  function normalizeMode(mode) {
7
7
  const normalized = String(mode || BASELINE_MODE).toLowerCase();
8
8
  if (normalized === "auto" || normalized === "")
@@ -178,13 +178,17 @@ export function createTrinityTool(deps) {
178
178
  return `\u2705 Switched to ${slot} slot (${result.ocModel}). Active now (no restart needed).`;
179
179
  }
180
180
  if (action === "mode") {
181
- if (!slot || !["budget", "quality", "speed", "longrun", "auto"].includes(slot)) {
182
- return `Provide mode: budget | quality | speed | longrun | auto`;
181
+ if (!slot)
182
+ return `Provide mode: budget | quality | speed | longrun | vibemax | vibeqmax | auto`;
183
+ const modeAlias = { vibemax: "vibemax", vibeqmax: "quality" };
184
+ const resolvedSlot = modeAlias[slot] || slot;
185
+ if (!["budget", "quality", "speed", "longrun", "vibemax", "auto"].includes(resolvedSlot)) {
186
+ return `Provide mode: budget | quality | speed | longrun | vibemax | vibeqmax | auto`;
183
187
  }
184
- const ok = deps.saveOptimizationMode(slot);
188
+ const ok = deps.saveOptimizationMode(resolvedSlot);
185
189
  if (!ok)
186
190
  return `Failed to write mode`;
187
- const tierMap = { budget: "cheap", quality: "brain", speed: "medium", longrun: "brain" };
191
+ const tierMap = { budget: "cheap", quality: "brain", speed: "medium", longrun: "brain", vibemax: "medium" };
188
192
  const tierSlot = tierMap[slot] || "cheap";
189
193
  deps.writeSelection("active_slot", tierSlot);
190
194
  deps.writeSelection("onboarding_mode", slot === "quality" || slot === "longrun" ? "strict" : "assist");
@@ -758,7 +762,7 @@ export function createTrinityTool(deps) {
758
762
  const probed = {
759
763
  brain: models.find(m => m.id === trinity.brain) || { id: trinity.brain, cost: deps._modelCost(trinity.brain), tier: deps._modelTier(trinity.brain) },
760
764
  medium: models.find(m => m.id === trinity.medium) || { id: trinity.medium, cost: deps._modelCost(trinity.medium), tier: deps._modelTier(trinity.medium) },
761
- cheap: models.find(m => m.id === trinity.cheap) || { id: trinity.cheap, cost: deps._modelCost(trinity.cheap), tier: deps._modelTier(trinity.cheap) }
765
+ cheap: models.find(m => m.id === trinity.cheap) || { id: trinity.cheap, cost: deps._modelCost(trinity.cheap), tier: deps._modelTier(trinity.cheap) },
762
766
  };
763
767
  const failed = [];
764
768
  for (const slot of ["brain", "medium", "cheap"]) {
@@ -24,7 +24,7 @@ export function resolveOptimizationMode(subRegime, stressMultiplier, optimizatio
24
24
  const normalized = String(optimizationMode || "auto").toLowerCase();
25
25
  if (normalized === "auto" || normalized === "")
26
26
  return autoSelectMode(subRegime || "INIT", stressMultiplier);
27
- if (normalized === "balanced" || normalized === "budget" || normalized === "quality" || normalized === "speed" || normalized === "longrun") {
27
+ if (normalized === "balanced" || normalized === "budget" || normalized === "quality" || normalized === "speed" || normalized === "longrun" || normalized === "vibemax") {
28
28
  return normalized;
29
29
  }
30
30
  return "budget";
@@ -70,7 +70,7 @@ export async function selectOptimizationModeRemote(subRegime, stressMultiplier,
70
70
  if (client) {
71
71
  const res = await client.blackboxSelectMode(subRegime || "INIT", Number(stressMultiplier ?? 0));
72
72
  const selected = String(res?.mode || "").toLowerCase();
73
- if (selected === "balanced" || selected === "budget" || selected === "quality" || selected === "speed" || selected === "longrun") {
73
+ if (selected === "balanced" || selected === "budget" || selected === "quality" || selected === "speed" || selected === "longrun" || selected === "vibemax") {
74
74
  return selected;
75
75
  }
76
76
  }
@@ -81,13 +81,14 @@ export async function selectOptimizationModeRemote(subRegime, stressMultiplier,
81
81
  }
82
82
  function computeControlVector(_state, _action, _optimizationMode) {
83
83
  const mode = resolveOptimizationMode(_state?.sub_regime, _state?.latest_stress_multiplier, _optimizationMode);
84
- const isStrict = mode === "quality";
84
+ const isStrict = mode === "quality" || mode === "vibemax";
85
85
  const isRelaxed = mode === "budget" || mode === "speed";
86
86
  const tierBias = mode === "quality" ? "brain"
87
87
  : mode === "speed" ? "medium"
88
- : mode === "longrun" ? "brain"
89
- : mode === "balanced" ? "auto"
90
- : "cheap";
88
+ : mode === "vibemax" ? "medium"
89
+ : mode === "longrun" ? "brain"
90
+ : mode === "balanced" ? "auto"
91
+ : "cheap";
91
92
  return {
92
93
  enforcement_mode: isStrict ? "strict" : isRelaxed ? "relaxed" : "normal",
93
94
  enforcement_reason: `[optimize: ${mode}] using safe offline defaults`,
@@ -121,7 +121,8 @@ export function createMcpServer(deps) {
121
121
  if (method === "GET" && path === "/status") {
122
122
  const state = deps.getState();
123
123
  const ok = await probeBackendHealth();
124
- json(res, 200, { ...state, backend_connected: ok === true, backend_health_url: BACKEND_HEALTH_URL });
124
+ const bb = deps.getBlackboxState();
125
+ json(res, 200, { ...state, backend_connected: ok === true, backend_health_url: BACKEND_HEALTH_URL, blackbox: bb ?? null });
125
126
  return;
126
127
  }
127
128
  if (method === "GET" && path === "/savings") {
@@ -191,6 +192,10 @@ export function createMcpServer(deps) {
191
192
  json(res, 200, deps.runProject());
192
193
  return;
193
194
  }
195
+ if (method === "GET" && path === "/blackbox") {
196
+ json(res, 200, deps.getBlackboxState() || {});
197
+ return;
198
+ }
194
199
  if (method === "POST" && path === "/trinity") {
195
200
  let body;
196
201
  try {
@@ -260,6 +265,32 @@ export function createMcpServer(deps) {
260
265
  json(res, 200, result);
261
266
  return;
262
267
  }
268
+ if (method === "POST" && path === "/blackbox/vector") {
269
+ let body;
270
+ try {
271
+ body = await parseBody(req);
272
+ }
273
+ catch {
274
+ json(res, 400, { error: "invalid request", status: 400 });
275
+ return;
276
+ }
277
+ deps.saveBlackboxVector(body);
278
+ json(res, 200, { ok: true });
279
+ return;
280
+ }
281
+ if (method === "POST" && path === "/blackbox/outcome") {
282
+ let body;
283
+ try {
284
+ body = await parseBody(req);
285
+ }
286
+ catch {
287
+ json(res, 400, { error: "invalid request", status: 400 });
288
+ return;
289
+ }
290
+ deps.saveBlackboxOutcome(body);
291
+ json(res, 200, { ok: true });
292
+ return;
293
+ }
263
294
  if (method === "GET" && path === "/") {
264
295
  serveDashboard(res, "/");
265
296
  return;
@@ -3,11 +3,11 @@
3
3
  // @ts-nocheck
4
4
  // Blackbox — theWay decision core ported to TypeScript.
5
5
  // Barrel export for all blackbox modules.
6
- export { buildAdvice, buildDecisionBlock, computeModality, humanReadableAction, compressMetrics, compressUncertainty, compressEntropy, enforceClosure, stabilityScore, shouldUseFastPath, buildCautionNote, scoreUsefulness, getFallbackPlan, getActionSuggestion, getCuriosityPrompt, } from "./advice-layer.js";
7
- export { classifySituation, getActions, recommendAction, getSituationTypes, } from "./taxonomy.js";
6
+ export { buildAdvice, buildDecisionBlock, computeModality, humanReadableAction, compressMetrics, compressUncertainty, compressEntropy, enforceClosure, stabilityScore, shouldUseFastPath, buildCautionNote, scoreUsefulness, getFallbackPlan, getActionSuggestion, getCuriosityPrompt } from "./advice-layer.js";
7
+ export { classifySituation, getActions, recommendAction, getSituationTypes } from "./taxonomy.js";
8
8
  export { ResolutionTracker } from "./resolution-tracker.js";
9
9
  export { ExposureModel } from "./exposure-model.js";
10
- export { ACTION_TARGET, ACTION_TYPE, FALLBACK_PLANS, ACTION_SUGGESTIONS, CURIOSITY_PROMPTS, } from "./crew-constants.js";
11
- export { computeControlVector, buildControlHistoryEntry, REGIME_CONTROL_TABLE, } from "./meta-controller.js";
10
+ export { ACTION_TARGET, ACTION_TYPE, FALLBACK_PLANS, ACTION_SUGGESTIONS, CURIOSITY_PROMPTS } from "./crew-constants.js";
11
+ export { computeControlVector, buildControlHistoryEntry, REGIME_CONTROL_TABLE } from "./meta-controller.js";
12
12
  export { vibemaxSelectMode, vibemaxPipeline, predictVibeMaX, trainVibeMaXModelFromTelemetry, getVibeMaXModelMeta, resetVibeMaXPipeline } from "./vibemax.js";
13
13
  export { PivotCache } from "./pivot-cache.js";
@@ -193,11 +193,6 @@ export function computeControlVector(state, action, optimizationMode) {
193
193
  if (effectiveMode === "auto") {
194
194
  effectiveMode = autoSelectMode(regime, state.latest_stress_multiplier);
195
195
  }
196
- if (effectiveMode === "vibemax") {
197
- const baseMode = autoSelectMode(regime, state.latest_stress_multiplier);
198
- const vibemaxQuality = ["quality", "longrun", "audit"];
199
- effectiveMode = vibemaxQuality.includes(baseMode) ? "vibemax" : "budget";
200
- }
201
196
  // Apply mode deltas on top of base (only for non-balanced modes)
202
197
  const delta = effectiveMode !== "balanced" ? (MODE_DELTAS[effectiveMode] || {}) : {};
203
198
  const overridden = {