@herjarsa/omo-meta-governor 0.17.2 → 0.18.0

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/README.md CHANGED
@@ -457,6 +457,103 @@ No user action required. Two behavior changes:
457
457
  | v0.17.1 | ✅ | Audit args fix |
458
458
  | v0.17.2 | ✅ | Gap C (escalation live), Q (file paths), D (config fields), I (delivery expired) |
459
459
 
460
+
461
+
462
+ ## v0.17.3 — Fix Gap I properly (patch)
463
+
464
+ v0.17.3 is a single-bug patch. During live verification of v0.17.2, Gap I was found to be incompletely fixed.
465
+
466
+ ### The bug (v0.17.2 cosmetic fix)
467
+
468
+ The `verifyDelivery` export signature was widened to include `"expired"` in v0.17.2, and the bridge tools' title/output text was updated to handle it. **BUT the underlying `pollForDelivery` helper was still collapsing `"expired"` → `"pending"` silently:**
469
+
470
+ ```ts
471
+ // v0.17.2 (BUG):
472
+ return status === "delivered" ? "delivered" : "pending"
473
+ ```
474
+
475
+ So bridge tools could never report `"expired"` to the user, even though the registry correctly tracked it. Live verification confirmed: `deliveryStatus` always showed `"pending"`.
476
+
477
+ ### The fix (v0.17.3)
478
+
479
+ ```ts
480
+ // v0.17.3:
481
+ return await pendingRegistryRef.awaitDelivery({ sessionID, mcpTool, timeoutMs })
482
+ ```
483
+
484
+ Now the actual status from the registry propagates through. `"expired"` flows end-to-end to the bridge tool's `metadata.deliveryStatus` and title.
485
+
486
+ ### Tests
487
+
488
+ Added 3 RED tests in `src/custom-tools.test.ts`:
489
+ - Returns `"expired"` when registry entry exists past timeout (real registry instance)
490
+ - Returns `"delivered"` when `markDelivered` fires before timeout
491
+ - Returns `"pending"` when no registry is configured
492
+
493
+ ### Test & build status
494
+
495
+ - **525/525 tests pass** (up from 522 in v0.17.2 — 3 new tests for pollForDelivery).
496
+ - `bun run typecheck` clean.
497
+ - `bun build.ts` clean (0.34 MB dist).
498
+
499
+ ### Migration
500
+
501
+ No user action required. Bridge tools will now correctly distinguish all three delivery states:
502
+ - `"delivered"` — LLM's MCP tool call was observed within 1.5s
503
+ - `"expired"` — TTL elapsed without delivery (entry expires after 10s, but bridge tool sees this immediately as "expired" when polling times out at 1.5s)
504
+ - `"pending"` — no registry configured (graceful degradation for tests/mocks)
505
+
506
+ ### Audit roadmap (status as of v0.17.3)
507
+
508
+ | Release | Status | Scope |
509
+ |---------|--------|-------|
510
+ | v0.15.1 → v0.17.2 | ✅ | All audit findings + 5 gap fixes |
511
+ | v0.17.3 | ✅ | Gap I real fix (pollForDelivery returns "expired") |
512
+
513
+ Two remaining gaps documented but require SDK support to fix:
514
+ - `recentTurnTokens: []` — token-predictor signal dead (10% of score); needs per-turn token counts from OpenCode SDK
515
+ - `agentName` defaults to `"unknown"` — cosmetic, no functional impact
516
+
517
+
518
+
519
+ ## v0.18.0 — Audit remediation: 7+ silent config drops + circular ref crash
520
+
521
+ v0.18.0 is a thorough-audit patch release. Each fix addresses a bug found by testing every public function with edge cases and adversarial inputs.
522
+
523
+ ### Highlights
524
+
525
+ | # | Bug | Severity | Fix |
526
+ |---|-----|----------|-----|
527
+ | 1 | `file-logger.redactData` crashed on circular references with stack overflow | 🔴 CRITICAL | `WeakSet` guard + `try/catch` fallback |
528
+ | 2 | `loadOrchestratorConfig` only projected `closedLoop.saveDecisions` — `enabled`, `minSeverityToLearn`, `maxLessonsPerSession`, `saveLessons` were silently dropped | 🔴 CRITICAL | Project all 5 fields |
529
+ | 3 | `loadOrchestratorConfig` didn't project `decision.warnMessageTemplate`, `escalateMessageTemplate`, `stopMessageTemplate` | 🟠 HIGH | Project all 3 templates |
530
+ | 4 | `loadOrchestratorConfig` didn't project `scoring.paralysisThreshold`, `defaultEscalationTarget` | 🟠 HIGH | Project all fields |
531
+ | 5 | `loadOrchestratorConfig` had `memory.timeoutMs` field name mismatch (schema said `agentmemoryTimeoutMs`) | 🟠 HIGH | Accept both names |
532
+ | 6 | `isMetaGovernorEnabled` only checked top-level `enabled`, not `meta_governor.enabled` (wrapped shape from `opencode.jsonc`) | 🟠 HIGH | Check both shapes |
533
+ | 7 | `createMetricsCollector` crashed when called without config (`config.version` on `undefined`) | 🟠 HIGH | Accept `Partial<MetricsCollectorConfig>` |
534
+ | 8 | `metrics.inc` crashed on unknown event names (`bucket.count++` on `undefined`) | 🟠 HIGH | Guard `if (!bucket) return` |
535
+ | 9 | `isNewerVersion` returned `false` for `installed=null` (no upgrade triggered for fresh installs) | 🟡 MEDIUM | Return `true` when installed is null AND latest is valid |
536
+
537
+ ### Test & build status
538
+
539
+ - **557/557 tests pass** (up from 530 in v0.17.3 — 27 new tests for the audit fixes).
540
+ - `bun run typecheck` clean.
541
+ - `bun build.ts` clean (0.34 MB dist).
542
+ - `npm pack --dry-run` validated.
543
+
544
+ ### Migration
545
+
546
+ No user action required. The fix to `loadOrchestratorConfig` means **users who were setting `closedLoop.maxLessonsPerSession` or other previously-dropped fields will now see those values actually take effect**. If you had a config like `{ "closedLoop": { "maxLessonsPerSession": 50 } }` before v0.18.0, it was silently being overridden to 20. Starting v0.18.0, the value 50 is now respected.
547
+
548
+ ### Audit roadmap (status as of v0.18.0)
549
+
550
+ | Release | Status | Scope |
551
+ |---------|--------|-------|
552
+ | v0.15.1 → v0.17.3 | ✅ | All audit findings + deferred items + audit args fix + gap fixes |
553
+ | v0.18.0 | ✅ | 7 silent config drops + circular ref crash + metrics crashes + upgrade trigger |
554
+
555
+ This release closes the final round of gaps found by a thorough function-by-function audit. The plugin now correctly projects **all** user configuration, handles **all** circular reference cases, and fails safely on **all** missing-input scenarios.
556
+
460
557
  ## Auto-upgrade (v0.12.0)
461
558
 
462
559
  On plugin load, queries npm/pip registries to check whether newer versions
package/dist/config.d.ts CHANGED
@@ -12,10 +12,18 @@ export interface MetaGovernorPluginConfig {
12
12
  decision?: {
13
13
  maxHistoryPerSession?: number;
14
14
  forceContinueAfterStops?: number;
15
+ /** v0.18.0: custom warning message template. */
16
+ warnMessageTemplate?: string;
17
+ /** v0.18.0: custom escalation message template. */
18
+ escalateMessageTemplate?: string;
19
+ /** v0.18.0: custom stop message template. */
20
+ stopMessageTemplate?: string;
15
21
  };
16
22
  /** Memory aggregator (PR 2) */
17
23
  memory?: {
18
24
  agentmemoryTimeoutMs?: number;
25
+ /** v0.18.0: alias for agentmemoryTimeoutMs (was the only name projected). */
26
+ timeoutMs?: number;
19
27
  magicContextTimeoutMs?: number;
20
28
  boulderStateTimeoutMs?: number;
21
29
  query?: string;
@@ -33,9 +41,16 @@ export interface MetaGovernorPluginConfig {
33
41
  warnThreshold?: number;
34
42
  escalateThreshold?: number;
35
43
  stopThreshold?: number;
44
+ /** v0.18.0: was silently dropped by loadOrchestratorConfig */
45
+ paralysisThreshold?: number;
46
+ /** v0.18.0: was silently dropped by loadOrchestratorConfig */
47
+ defaultEscalationTarget?: "oracle" | "user";
36
48
  };
37
49
  /** Closed-loop learning (PR 3) */
38
50
  closedLoop?: {
51
+ enabled?: boolean;
52
+ minSeverityToLearn?: "leve" | "media" | "grave";
53
+ maxLessonsPerSession?: number;
39
54
  saveDecisions?: boolean;
40
55
  saveLessons?: boolean;
41
56
  };
@@ -77,7 +92,7 @@ export declare function loadOrchestratorConfig(pluginConfig: Partial<MetaGoverno
77
92
  /**
78
93
  * Check whether the MetaGovernor is enabled. Returns false if config is undefined.
79
94
  */
80
- export declare function isMetaGovernorEnabled(config: MetaGovernorPluginConfig | undefined): boolean;
95
+ export declare function isMetaGovernorEnabled(config: Partial<MetaGovernorPluginConfig> | undefined): boolean;
81
96
  /**
82
97
  * Load orchestrator config from all available sources: config file (JSONC)
83
98
  * with priority: CLI inline > project config > user config > defaults.