vibeostheog 0.23.32 → 0.23.33

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,7 @@
1
+ ## 0.23.33
2
+ - feat: wire forensic + audit into ML pipeline — classifyTurnSimple detects security/forensic intent, autoSelectMode returns audit/forensic mode
3
+
4
+
1
5
  ## 0.23.32
2
6
  - test: 14 agent_mode integration tests — plan only for complex regimes, stress-gated
3
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.23.32",
3
+ "version": "0.23.33",
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",
package/src/index.js CHANGED
@@ -25,7 +25,7 @@ import { createTrinityTool } from "./lib/trinity-tool.js";
25
25
  import { classifyAndRankModels, modelToCcAlias, discoverAvailableModels, probeModel } from "./lib/trinity-rebuild.js";
26
26
  import { _appendFooter } from "./lib/hooks/footer.js";
27
27
  import { onToolExecuteBefore, onToolExecuteAfter, setToolDirectory } from "./lib/hooks/tool-execute.js";
28
- import { onMessagesTransform, onSystemTransform, latestUserIntent } from "./lib/hooks/chat-transform.js";
28
+ import { onMessagesTransform, onSystemTransform, latestUserIntent, ensureProjectSkill } from "./lib/hooks/chat-transform.js";
29
29
  import { onSessionCompacting } from "./lib/hooks/session-compact.js";
30
30
  import { onShellEnv, setShellDirectory } from "./lib/hooks/shell-env.js";
31
31
  function getVibeOSHome() {
@@ -67,6 +67,8 @@ let _mcpServerStartupPromise = null;
67
67
  let context7Seen = new Set();
68
68
  let _prevOutputText = "";
69
69
  let _deferredBootstrapDone = false;
70
+ let _skillsEnsured = new Set();
71
+
70
72
  let _runDeferredStartupBootstrap = null;
71
73
  const SAVE_EST = {
72
74
  WRITE_EDIT: 0.005,
@@ -452,6 +454,13 @@ export async function DelegationEnforcer({ client, directory } = {}) {
452
454
  setCurrentProjectName(directory ? directory.split("/").pop() : "unknown");
453
455
  }
454
456
  ensureDeferredBootstrap();
457
+ if (directory && hookFp && !_skillsEnsured.has(hookFp)) {
458
+ try {
459
+ ensureProjectSkill(directory, hookFp);
460
+ _skillsEnsured.add(hookFp);
461
+ } catch (_e) {}
462
+ }
463
+
455
464
  onToolExecuteBefore._directory = directory;
456
465
  return onToolExecuteBefore(input, output);
457
466
  },
@@ -466,6 +475,13 @@ export async function DelegationEnforcer({ client, directory } = {}) {
466
475
  },
467
476
  "experimental.chat.messages.transform": async (_input, output) => {
468
477
  ensureDeferredBootstrap();
478
+ if (directory && hookFp && !_skillsEnsured.has(hookFp)) {
479
+ try {
480
+ ensureProjectSkill(directory, hookFp);
481
+ _skillsEnsured.add(hookFp);
482
+ } catch (_e) {}
483
+ }
484
+
469
485
  return onMessagesTransform(_input, output);
470
486
  },
471
487
  "experimental.session.compacting": async (_input, output) => {
@@ -478,6 +494,13 @@ export async function DelegationEnforcer({ client, directory } = {}) {
478
494
  setCurrentProjectName(directory ? directory.split("/").pop() : "unknown");
479
495
  }
480
496
  ensureDeferredBootstrap();
497
+ if (directory && hookFp && !_skillsEnsured.has(hookFp)) {
498
+ try {
499
+ ensureProjectSkill(directory, hookFp);
500
+ _skillsEnsured.add(hookFp);
501
+ } catch (_e) {}
502
+ }
503
+
481
504
  onSystemTransform._directory = directory;
482
505
  onSystemTransform._activeJob = activeJob;
483
506
  onSystemTransform._briefedProjects = systemBriefedProjects;
@@ -500,6 +523,13 @@ export async function DelegationEnforcer({ client, directory } = {}) {
500
523
  setCurrentProjectName(directory ? directory.split("/").pop() : "unknown");
501
524
  }
502
525
  ensureDeferredBootstrap();
526
+ if (directory && hookFp && !_skillsEnsured.has(hookFp)) {
527
+ try {
528
+ ensureProjectSkill(directory, hookFp);
529
+ _skillsEnsured.add(hookFp);
530
+ } catch (_e) {}
531
+ }
532
+
503
533
  await _appendFooter(_input, output, directory);
504
534
  },
505
535
  "message.updated": async (_input, output) => {
@@ -509,6 +539,13 @@ export async function DelegationEnforcer({ client, directory } = {}) {
509
539
  setCurrentProjectName(directory ? directory.split("/").pop() : "unknown");
510
540
  }
511
541
  ensureDeferredBootstrap();
542
+ if (directory && hookFp && !_skillsEnsured.has(hookFp)) {
543
+ try {
544
+ ensureProjectSkill(directory, hookFp);
545
+ _skillsEnsured.add(hookFp);
546
+ } catch (_e) {}
547
+ }
548
+
512
549
  await _appendFooter(_input, output, directory);
513
550
  },
514
551
  tool: {
@@ -96,6 +96,9 @@ export function classifyTurnSimple(userText) {
96
96
  const lower = String(userText || "").trim();
97
97
  if (!lower)
98
98
  return "INIT";
99
+ if (/(security|vulnerability|audit|owasp|inject|exploit|penetration|cve|attack|threat|compliance|gdpr|privacy|encrypt|xss|csrf|authn|authz|pentest|forensic|research|analyze dependencies|license audit|deep analysis|investigate|root cause|reverse engineer|disassemble|memory dump|core dump)/i.test(lower)) {
100
+ return "FORENSIC";
101
+ }
99
102
  // Q&A / research patterns -> EXPLORING (relaxed enforcement)
100
103
  if (/^(how|what|why|when|where|who|can you|could you|tell me|explain|describe|show|list|check|is there|are there|does|do you|summarize|elaborate|clarify|inspect|trace|find|search|look|read|show me|dump)/i.test(lower)) {
101
104
  return "EXPLORING";
@@ -12,6 +12,8 @@ function getVibeOSHome() {
12
12
  function autoSelectMode(subRegime, stressMultiplier) {
13
13
  const regime = String(subRegime || "INIT").toUpperCase();
14
14
  const stress = Number(stressMultiplier ?? 0);
15
+ if (regime === "AUDIT" || regime === "FORENSIC")
16
+ return regime.toLowerCase();
15
17
  if (regime === "LOOPING")
16
18
  return "speed";
17
19
  if (regime === "CONVERGING" || regime === "CLOSED")