@herjarsa/omo-meta-governor 0.51.0 → 0.53.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
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Adherence tracking — detects when the agent IGNORES an already-injected
3
+ * directive (same rule violated again after the injection was drained).
4
+ *
5
+ * Why this exists: protocol violations are injected into the agent context
6
+ * (system.transform drain, FASE 11 11e), but nothing measured whether the
7
+ * agent actually complied afterwards. A repeat violation of the same rule
8
+ * AFTER the agent saw the directive is evidence of non-adherence, not of a
9
+ * missing directive — so it is counted separately (`directives_ignored`)
10
+ * instead of re-injecting louder each time.
11
+ *
12
+ * Lifecycle (per session):
13
+ * 1. tool.execute.before detects violation of rule R.
14
+ * 2. If R was already injected (drained) in this session → reincidencia:
15
+ * `directives_ignored` + `adherence_ignored` log. Never escalates by
16
+ * itself for leve/media (counting only — explicit below).
17
+ * 3. system.transform drains pendingViolations → each distinct rule R in
18
+ * the drained items is recorded via `recordInjection` (injected = the
19
+ * agent saw it; detection alone does NOT mark — the agent may never
20
+ * have seen an undrained queue).
21
+ * 4. Scoring: ONLY grave reincidence with repeatCount >= 2 (third strike
22
+ * counting the original) floors the decision to `stop`. The
23
+ * stop → paralysis → continue loop stays supreme: a persistent false
24
+ * positive still resolves via paralysisOverride forcing continue after
25
+ * N consecutive stops, so adherence can never deadlock a session.
26
+ *
27
+ * Severity policy (explicit):
28
+ * - leve / media reincidence: counted in `directives_ignored`, NEVER
29
+ * escalates on its own. See `adherenceFloor` — it returns null for
30
+ * non-grave severities unconditionally.
31
+ * - grave reincidence: counted; escalates to `stop` ONLY at repeatCount
32
+ * >= ADHERENCE_STOP_REPEAT_THRESHOLD (2). Below that, the Wave B grave
33
+ * floor (continue/warn → escalate) still applies as before.
34
+ *
35
+ * All helpers here are pure (no I/O, no Date.now, no globals) so they are
36
+ * unit-testable without the plugin factory.
37
+ */
38
+ /** Rule -> times the rule's directive was drained (seen by the agent). */
39
+ export type InjectedRules = Record<string, number>;
40
+ /**
41
+ * How many times a rule's directive was already injected when a new
42
+ * violation arrives. repeatCount >= ADHERENCE_STOP_REPEAT_THRESHOLD means
43
+ * the third strike (original + 2 repeats).
44
+ */
45
+ export declare const ADHERENCE_STOP_REPEAT_THRESHOLD = 2;
46
+ /** Cap of distinct rules tracked per session (bounds per-session memory). */
47
+ export declare const ADHERENCE_MAX_RULES = 50;
48
+ /**
49
+ * Record that rule `rule` was injected (drained into agent context).
50
+ * Returns a NEW record (input is not mutated). When the record already
51
+ * holds ADHERENCE_MAX_RULES distinct rules, the new rule is dropped so a
52
+ * noisy session cannot grow memory unboundedly.
53
+ */
54
+ export declare function recordInjection(rules: Readonly<InjectedRules>, rule: string): InjectedRules;
55
+ /**
56
+ * How many times `rule` was already injected in this session (0 = never —
57
+ * the current violation is the first occurrence, NOT a reincidencia).
58
+ */
59
+ export declare function countRepeat(rules: Readonly<InjectedRules>, rule: string): number;
60
+ /**
61
+ * Adherence escalation floor. Returns "stop" ONLY for grave reincidence at
62
+ * or above the repeat threshold. leve/media ALWAYS return null (counted,
63
+ * never escalated — see module docstring). Unknown severities return null.
64
+ */
65
+ export declare function adherenceFloor(severity: string, repeatCount: number): "stop" | null;
66
+ /**
67
+ * Extract distinct rule names from drained violation entry strings.
68
+ * Entries are formatted as `[SEVERITY] rule: detail` (see plugin.ts queue
69
+ * site). Returns distinct rules in first-seen order; unparseable entries
70
+ * are skipped (never throw — drain is best-effort).
71
+ */
72
+ export declare function parseInjectedRules(items: readonly string[]): string[];
@@ -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,26 @@ 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 at the final-gate
94
+ * (`<promise>DONE</promise>`) AND when the scoring engine reaches the
95
+ * stop band (action === "stop"). warn/escalate decisions log but do
96
+ * NOT invoke Oracle mid-work. Brake on emergencies, mandatory at done.
97
+ * (B3: wording copied from enforcement-resources.ts buildOracleRule;
98
+ * the previous text said "ONLY at the final-gate ... AND when",
99
+ * which is self-contradictory.)
98
100
  *
99
101
  * - `"off"`: Oracle is never invoked. The post-wave gate still requires
100
102
  * `oracleVerified` — set it manually via `omo_recall` if you need it.
101
103
  */
102
104
  oracle?: {
103
- /** @default "per-stop" */
105
+ /** @default "final-only" */
104
106
  frequency?: "per-stop" | "final-only" | "off";
105
107
  };
106
108
  /** Intervention config for visible decision injection. */
@@ -115,7 +117,8 @@ export interface MetaGovernorPluginConfig {
115
117
  minActionForMessage?: "warn" | "escalate" | "stop";
116
118
  /**
117
119
  * v0.10.0: rate-limit interventions to break instruction loops.
118
- * @default 3
120
+ * v0.51.x (Wave A P3): severity-tiered quota — only escalate/stop consume.
121
+ * @default 5
119
122
  */
120
123
  maxInterventionsPerSession?: number;
121
124
  /**
@@ -220,6 +223,11 @@ export interface MetaGovernorPluginConfig {
220
223
  injectIntoSystem?: boolean;
221
224
  auditToolCalls?: boolean;
222
225
  };
226
+ /** Wave B workflow gates (explore-before-implement). All default false. */
227
+ workflowGates?: {
228
+ enabled?: boolean;
229
+ requirePlan?: boolean;
230
+ };
223
231
  /** Graph sync config for auto-initializing codegraph/graphify. */
224
232
  graphSync?: {
225
233
  /** @default true */
@@ -263,20 +271,28 @@ export interface MetaGovernorPluginConfig {
263
271
  * Default false (opt-in — multi-project users want explicit control). */
264
272
  addToGlobalGraph?: boolean;
265
273
  };
266
- /** v0.28.0: CLI-Anything hub auto-install + auto-upgrade. Opt-in.
274
+ /** v0.28.0: CLI-Anything hub auto-install + auto-upgrade. Opt-out
275
+ * (enabled by default; set `cliAnything.enabled: false` to disable).
267
276
  * When enabled, the plugin ensures `cli-anything-hub` (pip) and
268
- * `cli-hub-meta-skill` (npx skills) are installed and current. */
277
+ * `cli-hub-meta-skill` (npx skills) are installed and current.
278
+ * Canonical projection is `!== false` (see loadOrchestratorConfig
279
+ * cliAnything projection and orchestrator.ts CLI-Anything defaults). */
269
280
  cliAnything?: {
270
- /** @default false */
281
+ /** @default true (opt-out via `cliAnything.enabled: false`;
282
+ * canonical `!== false` projection in orchestrator.ts) */
271
283
  enabled?: boolean;
272
284
  /** @default true */
273
285
  autoInstall?: boolean;
274
286
  /** @default true */
275
287
  autoUpgrade?: boolean;
288
+ /** @default newPluginPaths().cliAnythingUpgradeCheck
289
+ * (effective default applied at call-site, plugin.ts) */
276
290
  cachePath?: string;
277
- /** @default 86400000 */
291
+ /** @default 86400000 (24h; effective default applied at call-site, plugin.ts:649) */
278
292
  upgradeCheckTtlMs?: number;
293
+ /** @default "cli-hub" */
279
294
  cliHubBin?: string;
295
+ /** @default "npx skills" */
280
296
  skillsBin?: string;
281
297
  /** @default "global" */
282
298
  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.