@herjarsa/omo-meta-governor 0.51.0 → 0.52.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
@@ -29,6 +29,8 @@
29
29
  - [Auto-upgrade (v0.26.0)](#auto-upgrade-v0260)
30
30
  - [Git hooks](#git-hooks)
31
31
  - [Process safeguards](#process-safeguards)
32
+ - [CLI-Anything hub (v0.28.0)](#cli-anything-hub-v0280)
33
+ - [On-demand upgrades (W4-C)](#on-demand-upgrades-w4-c)
32
34
  - [Persistence & observability](#persistence--observability)
33
35
  - [CI monitor (v0.25.0)](#ci-monitor-v0250)
34
36
  - [Configuration reference](#configuration-reference)
@@ -84,18 +86,18 @@ Minimal config to enable the governance pipeline:
84
86
  }
85
87
  ```
86
88
 
87
- ### Oracle frequency (v0.38.4+, Option D)
89
+ ### Oracle frequency
88
90
 
89
91
  Controls when the plugin invokes Oracle for verification:
90
92
 
91
93
  ```jsonc
92
94
  {
93
95
  "oracle": {
94
- // "per-stop" (default): Oracle invoked ONLY at the final-gate AND when
96
+ // "final-only" (default): Oracle invoked ONLY at the final-gate. Zero mid-work.
97
+ // "per-stop": Oracle invoked ONLY at the final-gate AND when
95
98
  // scoring reaches stop band (action === "stop"). warn/escalate log only.
96
- // "final-only": Oracle invoked ONLY at the final-gate. Zero mid-work.
97
99
  // "off": Oracle never invoked automatically. Set oracleVerified manually.
98
- "frequency": "per-stop"
100
+ "frequency": "final-only"
99
101
  }
100
102
  }
101
103
  ```
@@ -103,6 +105,18 @@ Controls when the plugin invokes Oracle for verification:
103
105
  The `<promise>DONE</promise>` / `<promise>PLAN-COMPLETE</promise>` final-gate
104
106
  ALWAYS invokes Oracle regardless of `oracle.frequency`.
105
107
 
108
+ | `frequency` | Mid-work Oracle | Final-gate Oracle | Typical invocations / session |
109
+ |---|---|---|---|
110
+ | `final-only` (default) | Never — even `stop` decisions log without an Oracle prompt | Always | Exactly 1 (final-gate); zero mid-work interruptions |
111
+ | `per-stop` | ONLY when scoring reaches the stop band (`action === "stop"`); `warn`/`escalate` log only (`escalation suppressed by oracle.frequency`) | Always | 1 (final-gate) + 1 per stop-level emergency |
112
+ | `off` | Never invoked automatically | Never — set `oracleVerified` manually (e.g. via `omo_recall`) | 0 |
113
+
114
+ Implementation: `selectEscalationTarget()` in `src/scoring-engine.ts`
115
+ returns `null` for `off`/`final-only` (any action) and for `per-stop` unless
116
+ action is `"stop"`; `src/plugin.ts` respects the `null` (logs `escalation
117
+ suppressed by oracle.frequency`) while the DONE final-gate handler
118
+ (`detectPlanCompleteSignal` path) invokes Oracle separately.
119
+
106
120
  ---
107
121
 
108
122
  ## What it does
@@ -404,6 +418,61 @@ Config: `graphSync.killOrphanedOnInit` (default `true`) — on graph-sync
404
418
  init the plugin sweeps orphaned `graphify`/`codegraph` processes left
405
419
  by previous crashed runs. Set to `false` to disable the sweep.
406
420
 
421
+ ### CLI-Anything hub (v0.28.0)
422
+
423
+ Parallel to graph-sync, the plugin ensures the CLI-Anything ecosystem
424
+ (`cli-hub` registry/installer + `npx skills` meta-skill) is installed and
425
+ current. **Opt-out: enabled by default** — every default projection uses
426
+ `!== false`, so omitting the block means ON:
427
+
428
+ ```jsonc
429
+ {
430
+ "meta_governor": {
431
+ "cliAnything": {
432
+ "enabled": true, // default true — opt-out
433
+ "autoInstall": true, // default true
434
+ "autoUpgrade": true, // default true
435
+ "upgradeCheckTtlMs": 86400000 // 24h registry-query TTL
436
+ }
437
+ }
438
+ }
439
+ ```
440
+
441
+ To disable (e.g. offline machines, hermetic tests):
442
+
443
+ ```jsonc
444
+ {
445
+ "meta_governor": {
446
+ "cliAnything": { "enabled": false }
447
+ }
448
+ }
449
+ ```
450
+
451
+ Independent of `graphSync.enabled` (W1-A1 desanidado): disabling graphSync
452
+ does NOT disable cliAnything and vice-versa. Both run fire-and-forget at
453
+ factory invocation, never blocking session start. The test seam
454
+ `__test_onCliAnythingInit` mirrors `__test_onGraphSyncInit` for placement
455
+ assertions without spawning real subprocesses.
456
+
457
+ ### On-demand upgrades (W4-C)
458
+
459
+ Two tools expose the backend upgrade path on demand (codegraph + graphify):
460
+
461
+ | Tool | What it does | Use case |
462
+ |------|--------------|----------|
463
+ | `omo_upgrade_check` | Dry-run version table (installed / latest / upgrade-needed per backend). NEVER installs anything. | "Is an upgrade pending?" — safe to call any time |
464
+ | `omo_upgrade_run` | Executes the upgrade path once. Respects the 24h TTL cache (`upgradeCheckTtlMs`, default `86400000`): skips with `skipped:true` when the cache is fresh. Best-effort, never throws. | "Upgrade the backends now" |
465
+
466
+ Both are registered on all three surfaces: V1 `tool` hook (governance-enabled
467
+ and governance-disabled paths), V2 (`registerOmoTools`), and MCP
468
+ (`getAdapters()` + `MCP_TOOL_NAMES`).
469
+
470
+ > **Nota `syncIntervalMs` (startup-only):** `syncIntervalMs` applies ONLY to
471
+ > the `skillHub` registry sync (periodic background refresh of the skill
472
+ > catalog). `omo_upgrade_check` / `omo_upgrade_run` are **on-demand /
473
+ > startup-only** — they NEVER use `setInterval` and never poll in the
474
+ > background.
475
+
407
476
  ## MCP server mode (v0.31.0)
408
477
 
409
478
  OpenCode Desktop and OpenChamber spawn `opencode serve` in HTTP/sidecar mode
@@ -575,6 +644,7 @@ All configuration lives under the `meta_governor` key in
575
644
  | `protocolEnforcement` | object | — | Sisyphus protocol enforcement. |
576
645
  | `skillPriming` | object | — | Proactive skill-selection nudge (v0.20.0). |
577
646
  | `graphSync` | object | — | Graph synchronization (auto-init codegraph/graphify). |
647
+ | `cliAnything` | object | — | CLI-Anything hub auto-install + auto-upgrade (opt-out, enabled by default). |
578
648
 
579
649
  ### `decision`
580
650
 
@@ -678,6 +748,19 @@ All configuration lives under the `meta_governor` key in
678
748
  | `upgradeCachePath` | string | — | **v0.26.0** — path for the upgrade cache file. |
679
749
  | `checkGraphifyNeedsUpdate` | boolean | `true` | **v0.26.0** — run `graphify check-update` after upgrade. |
680
750
 
751
+ ### `cliAnything`
752
+
753
+ | Field | Type | Default | Description |
754
+ |-------|------|---------|-------------|
755
+ | `enabled` | boolean | `true` | Opt-out master switch — set `cliAnything.enabled:false` to disable. Canonical `!== false` projection. |
756
+ | `autoInstall` | boolean | `true` | Auto-install `cli-hub` + meta-skill when missing. |
757
+ | `autoUpgrade` | boolean | `true` | Auto-upgrade on factory init (TTL-gated). |
758
+ | `cachePath` | string | — | Upgrade-check cache file (effective default `newPluginPaths().cliAnythingUpgradeCheck`). |
759
+ | `upgradeCheckTtlMs` | number | `86400000` | Min ms between registry queries (24h). Effective default applied at call-site (`plugin.ts`). |
760
+ | `cliHubBin` | string | `"cli-hub"` | Path to `cli-hub` binary. |
761
+ | `skillsBin` | string | `"npx skills"` | Path to `npx skills` invocation. |
762
+ | `installScope` | enum | `"global"` | `"global"` \| `"project"`. |
763
+
681
764
  ---
682
765
 
683
766
  ## Architecture overview
@@ -16,6 +16,25 @@
16
16
  * - No file I/O, no MCP calls — just decision logic + DI write.
17
17
  */
18
18
  import type { AgentmemoryWriteBackend, ClosedLoopConfig, Decision, Deviation, LearnFromOutcomeInput, LearnFromOutcomeOutput } from "./types";
19
+ /**
20
+ * v0.51.1 (P1 lesson-spam guard, Wave A T-5df16a0e): minimum lesson
21
+ * confidence. Lessons below this are noise: 5311 Action-continue rows at
22
+ * confidence 0.3 flooded recall. Only high-value lessons persist.
23
+ */
24
+ export declare const MIN_LESSON_CONFIDENCE = 0.5;
25
+ /**
26
+ * Lesson confidence for a decision: the strongest available signal -
27
+ * max(|score|, best evidence confidence) - clamped to [0.3, 0.8].
28
+ * Evidence confidence matters: a warn at -0.4 backed by 0.8-confidence
29
+ * evidence is high-value signal, while a neutral continue near 0 with no
30
+ * evidence collapses to the 0.3 floor (below MIN_LESSON_CONFIDENCE).
31
+ */
32
+ export declare function lessonConfidenceForDecision(decision: Decision): number;
33
+ /**
34
+ * Neutral continues carry no learnable signal and must never persist as
35
+ * lessons - they were the entire 5311-row Action-continue spam class.
36
+ */
37
+ export declare function isNeutralContinueDecision(decision: Decision): boolean;
19
38
  /** Severity ordering for threshold comparison. */
20
39
  declare const SEVERITY_ORDER: Record<string, number>;
21
40
  /**
package/dist/config.d.ts CHANGED
@@ -83,24 +83,24 @@ export interface MetaGovernorPluginConfig {
83
83
  /** Model override for MetaGovernor internal LLM usage. */
84
84
  modelOverride?: ModelOverrideConfig;
85
85
  /**
86
- * v0.38.4: Oracle invocation frequency. Controls when the plugin invokes
86
+ * Oracle invocation frequency. Controls when the plugin invokes
87
87
  * Oracle for verification — reduces noisy mid-work escalations.
88
88
  *
89
- * - `"per-stop"` (default, Option D): Oracle is invoked ONLY at the
90
- * final-gate (`<promise>DONE</promise>`) AND when score crosses the
91
- * stop threshold (`≤ -stopThreshold`). warn/escalate decisions log
92
- * but do NOT inject an Oracle prompt mid-work. Best balance: silent
93
- * on normal work, brake on emergencies, mandatory at done.
94
- *
95
- * - `"final-only"` (Option A): Oracle is invoked ONLY at the final-gate.
89
+ * - `"final-only"` (default): Oracle is invoked ONLY at the final-gate.
96
90
  * Even stop-level decisions log without injecting an Oracle prompt.
97
- * Use when you want zero mid-work interruptions.
91
+ * Zero mid-work interruptions.
92
+ *
93
+ * - `"per-stop"`: Oracle is invoked ONLY at the final-gate
94
+ * (`<promise>DONE</promise>`) AND when score crosses the stop
95
+ * threshold (`≤ -stopThreshold`). warn/escalate decisions log but do
96
+ * NOT inject an Oracle prompt mid-work. Brake on emergencies,
97
+ * mandatory at done.
98
98
  *
99
99
  * - `"off"`: Oracle is never invoked. The post-wave gate still requires
100
100
  * `oracleVerified` — set it manually via `omo_recall` if you need it.
101
101
  */
102
102
  oracle?: {
103
- /** @default "per-stop" */
103
+ /** @default "final-only" */
104
104
  frequency?: "per-stop" | "final-only" | "off";
105
105
  };
106
106
  /** Intervention config for visible decision injection. */
@@ -115,7 +115,8 @@ export interface MetaGovernorPluginConfig {
115
115
  minActionForMessage?: "warn" | "escalate" | "stop";
116
116
  /**
117
117
  * v0.10.0: rate-limit interventions to break instruction loops.
118
- * @default 3
118
+ * v0.51.x (Wave A P3): severity-tiered quota — only escalate/stop consume.
119
+ * @default 5
119
120
  */
120
121
  maxInterventionsPerSession?: number;
121
122
  /**
@@ -220,6 +221,11 @@ export interface MetaGovernorPluginConfig {
220
221
  injectIntoSystem?: boolean;
221
222
  auditToolCalls?: boolean;
222
223
  };
224
+ /** Wave B workflow gates (explore-before-implement). All default false. */
225
+ workflowGates?: {
226
+ enabled?: boolean;
227
+ requirePlan?: boolean;
228
+ };
223
229
  /** Graph sync config for auto-initializing codegraph/graphify. */
224
230
  graphSync?: {
225
231
  /** @default true */
@@ -263,20 +269,28 @@ export interface MetaGovernorPluginConfig {
263
269
  * Default false (opt-in — multi-project users want explicit control). */
264
270
  addToGlobalGraph?: boolean;
265
271
  };
266
- /** v0.28.0: CLI-Anything hub auto-install + auto-upgrade. Opt-in.
272
+ /** v0.28.0: CLI-Anything hub auto-install + auto-upgrade. Opt-out
273
+ * (enabled by default; set `cliAnything.enabled: false` to disable).
267
274
  * When enabled, the plugin ensures `cli-anything-hub` (pip) and
268
- * `cli-hub-meta-skill` (npx skills) are installed and current. */
275
+ * `cli-hub-meta-skill` (npx skills) are installed and current.
276
+ * Canonical projection is `!== false` (see loadOrchestratorConfig
277
+ * cliAnything projection and orchestrator.ts CLI-Anything defaults). */
269
278
  cliAnything?: {
270
- /** @default false */
279
+ /** @default true (opt-out via `cliAnything.enabled: false`;
280
+ * canonical `!== false` projection in orchestrator.ts) */
271
281
  enabled?: boolean;
272
282
  /** @default true */
273
283
  autoInstall?: boolean;
274
284
  /** @default true */
275
285
  autoUpgrade?: boolean;
286
+ /** @default newPluginPaths().cliAnythingUpgradeCheck
287
+ * (effective default applied at call-site, plugin.ts) */
276
288
  cachePath?: string;
277
- /** @default 86400000 */
289
+ /** @default 86400000 (24h; effective default applied at call-site, plugin.ts:649) */
278
290
  upgradeCheckTtlMs?: number;
291
+ /** @default "cli-hub" */
279
292
  cliHubBin?: string;
293
+ /** @default "npx skills" */
280
294
  skillsBin?: string;
281
295
  /** @default "global" */
282
296
  installScope?: "global" | "project";
@@ -23,6 +23,19 @@ import type { SqliteBackend } from "./sqlite-backend";
23
23
  import type { GraphRetrieval } from "./graph-retrieval";
24
24
  import type { MetricsCollector } from "./metrics";
25
25
  import { type CodeGraphTools } from "./codegraph-tools";
26
+ /**
27
+ * Canonical routing suffix for a tool description (Wave C part 2).
28
+ *
29
+ * Why this exists: the agent sees tool descriptions on every turn, while the
30
+ * graph-priming injection fires once per session. Embedding the canonical
31
+ * routing line in the description keeps "which tool for which question"
32
+ * visible without depending on that one-shot injection.
33
+ *
34
+ * Why lookup by ROUTING_MATRIX: the matrix is the single canonical source -
35
+ * reusing it here keeps descriptions in sync when the matrix changes, instead
36
+ * of duplicating tool-name literals at each call site.
37
+ */
38
+ export declare function routingSuffixFor(toolName: string): string;
26
39
  /**
27
40
  * Module-level reference to the PendingDeliveryRegistry. The plugin
28
41
  * factory sets this once at startup. Bridge tools call it via
@@ -441,6 +454,29 @@ export declare function buildOmoHookStatusTool(deps: OmoHookStatusDeps): {
441
454
  args: {};
442
455
  execute(args: Record<string, never>, context: ToolContext): Promise<ToolResult>;
443
456
  };
457
+ export interface OmoUpgradeDeps {
458
+ cwd: string;
459
+ /** Optional runner DI seam for tests. When undefined, uses real subprocesses. */
460
+ runner?: (cmd: string, opts?: {
461
+ timeoutMs?: number;
462
+ }) => string;
463
+ /** Min ms between registry queries. Default 24h. */
464
+ upgradeCheckTtlMs?: number;
465
+ /** Override the upgrade cache file path. Tests use this. */
466
+ upgradeCachePath?: string;
467
+ }
468
+ /** `omo_upgrade_check` — dry-run version check. NEVER installs anything. */
469
+ export declare function buildOmoUpgradeCheckTool(deps: OmoUpgradeDeps): {
470
+ description: string;
471
+ args: {};
472
+ execute(args: Record<string, never>, context: ToolContext): Promise<ToolResult>;
473
+ };
474
+ /** `omo_upgrade_run` — perform the backend upgrade path once. Best-effort, never throws. */
475
+ export declare function buildOmoUpgradeRunTool(deps: OmoUpgradeDeps): {
476
+ description: string;
477
+ args: {};
478
+ execute(args: Record<string, never>, context: ToolContext): Promise<ToolResult>;
479
+ };
444
480
  export interface OmoCliAnythingDeps {
445
481
  cwd: string;
446
482
  /** Optional runner DI seam for tests. When undefined, uses real execSync. */
@@ -1,46 +1,23 @@
1
- /**
2
- * v0.37.0 (audit enforcement) — MCP enforcement resources for OpenChamber.
3
- *
4
- * Bug (audit v2 P0-2): In OpenChamber (HTTP mode), the plugin factory never
5
- * runs. Only MCP tools are exposed. All text-based instructions (Oracle rule 4,
6
- * agentmemory rule 8, skill-priming) live in `output.messages.push` /
7
- * `system.transform` which require plugin hooks. OpenChamber receives ZERO
8
- * enforcement.
9
- *
10
- * Fix: expose the rules as MCP resources that the agent can `resources/read`
11
- * at startup. Works in both plugin-CLI and OpenChamber modes.
12
- *
13
- * Contract:
14
- * - `meta-governor://rules/oracle` → Oracle gate rule text
15
- * - `meta-governor://rules/agentmemory` → omo_remember rule text
16
- * - `meta-governor://rules/skill-priming` → skill discovery rule text
17
- * - `meta-governor://rules/protocol` → Sisyphus protocol enforcement rules
18
- *
19
- * The returned text uses a `[SYSTEM-NUDGE]` prefix the LLM can detect.
20
- */
21
1
  export declare const ENFORCEMENT_RESOURCE_URIS: readonly ["meta-governor://rules/oracle", "meta-governor://rules/agentmemory", "meta-governor://rules/skill-priming", "meta-governor://rules/protocol"];
22
2
  export type EnforcementResourceUri = (typeof ENFORCEMENT_RESOURCE_URIS)[number];
23
3
  /**
24
- * Build the Oracle gate rule (v0.38.4 Option D — Oracle frequency).
4
+ * Build the Oracle gate rule (Oracle frequency).
25
5
  *
26
- * v0.38.4 REWRITE: Oracle is no longer auto-invoked mid-work for every
27
- * multi-file change. Instead, the `oracle.frequency` config controls when
28
- * Oracle fires:
29
- * - `"per-stop"` (default): Oracle invoked at the final-gate
6
+ * Oracle is no longer auto-invoked mid-work for every multi-file change.
7
+ * Instead, the `oracle.frequency` config controls when Oracle fires:
8
+ * - `"final-only"` (default): Oracle invoked ONLY at the final-gate.
9
+ * Even stop-level decisions log without invoking Oracle mid-work.
10
+ * - `"per-stop"`: Oracle invoked at the final-gate
30
11
  * (<promise>DONE</promise>) AND when the scoring engine reaches the
31
12
  * stop band (action === "stop"). warn/escalate log but do NOT
32
13
  * invoke Oracle mid-work.
33
- * - `"final-only"`: Oracle invoked ONLY at the final-gate. Even
34
- * stop-level decisions log without invoking Oracle mid-work.
35
14
  * - `"off"`: Oracle is NEVER invoked automatically. The agent must
36
15
  * set `oracleVerified` manually (e.g. via omo_recall).
37
16
  *
38
17
  * The DONE final-gate is ALWAYS Oracle-verified regardless of frequency.
39
18
  *
40
19
  * Same MCP resource contract as before — `meta-governor://rules/oracle`
41
- * still returns this text. The previous "INVOKE triggers per multi-file
42
- * change" was the source of the noise — now mid-work Oracle is
43
- * gated by score band, not file count.
20
+ * still returns this text.
44
21
  */
45
22
  export declare function buildOracleRule(): string;
46
23
  /**
@@ -186,6 +186,13 @@ export declare const logToFile: typeof _logToFile;
186
186
  * triggering a network call.
187
187
  */
188
188
  export declare function isNewerVersion(installed: string | null | undefined, latest: string | null | undefined): boolean;
189
+ /**
190
+ * P4 (v0.51.x): self-version STALE_CACHE polarity gate. Returns true ONLY
191
+ * when `latest` (npm registry) is strictly newer than `loaded` (running
192
+ * bundle) — equal versions (incl. "v"-prefix/whitespace variants) and
193
+ * loaded-newer-than-npm (local dev) stay silent. Pure: no I/O, no TTL.
194
+ */
195
+ export declare function shouldWarnStaleCache(loaded: string | null | undefined, latest: string | null | undefined): boolean;
189
196
  /**
190
197
  * v0.12.0: persisted cache of latest-version lookups so we don't
191
198
  * hammer npm/pip registries on every plugin load.