# What Happens When a Committed Model or Capability Disappears from Maka's Catalog

> Discover what happens when a committed model or capability disappears from Maka's catalog. Learn about catalog-drift events, fallback mechanisms, and session handling.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: internals
- Published: 2026-09-09

---

**When a committed model or capability disappears from Maka's catalog, the Runtime Host treats it as a catalog-drift event: the missing entry is silently removed from the live catalog, sessions using it receive a catalog-unavailable flag, and the UI displays a graceful fallback while existing in-flight tasks continue with their captured snapshot.**

Maka's **model/capability catalog** serves as the single source of truth for both the Runtime Host (the back-end execution engine) and the Desktop UI. Understanding how Maka handles **disappearing committed models or capabilities** is critical for building resilient AI applications that degrade gracefully when upstream provider catalogs change.

## How Maka Detects a Missing Committed Entry

The detection process begins during the **catalog refresh cycle**. The Host periodically reloads the provider's catalog—or triggers an immediate reload after a save operation. When a previously known entry is absent from the refreshed data, Maka flags this as catalog drift.

In `scripts/sync-model-metadata.mjs`, the projection-building function detects vanished providers and logs a drift report. This occurs at line 292, where the sync script compares the incoming catalog against the persisted state.

```javascript
// Conceptual flow from sync-model-metadata.mjs
// The actual detection happens during projection building
async function buildCatalogProjection(rawCatalog, persistedCatalog) {
  const driftReport = [];
  for (const [id, entry] of Object.entries(persistedCatalog)) {
    if (!rawCatalog[id]) {
      driftReport.push({ id, reason: 'vanished_from_provider' });
    }
  }
  return { projection: filteredCatalog, drift: driftReport };
}

```

## Host-Side Validation and Committed State Updates

Once drift is detected, the **Runtime Host validates the refreshed catalog** against the persisted "committed" snapshot. Missing entries are pruned from the committed view, while diagnostics for the absent items are preserved for audit purposes.

The test suite in [`packages/runtime/src/__tests__/skills.test.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/__tests__/skills.test.ts) confirms this behavior at line 127. Invalid—now missing—skills are excluded from the active catalog, yet their diagnostic records remain intact.

```typescript
// Excerpt pattern from skills.test.ts demonstrating exclusion logic
describe('catalog validation', () => {
  it('excludes invalid skills while preserving diagnostics', () => {
    const committedSkills = loadCommittedSnapshot();
    const refreshedCatalog = syncWithProvider();
    
    const validSkills = refreshedCatalog.filter(s => committedSkills.has(s.id));
    const diagnostics = generateDriftReport(committedSkills, refreshedCatalog);
    
    expect(validSkills).not.toContainEqual(expect.objectContaining({ id: 'vanished-skill' }));
    expect(diagnostics.missing).toContain('vanished-skill');
  });
});

```

## Session State and UI Degradation

Sessions that were using the now-missing model or capability receive a **catalog-unavailable flag**. UI components bound to the catalog—model pickers, capability selectors, and task configuration panels—render fallback states rather than crashing.

The test at [`apps/desktop/src/main/__tests__/task-submission-readiness-main.test.ts`](https://github.com/apache/maka/blob/main/apps/desktop/src/main/__tests__/task-submission-readiness-main.test.ts) (line 43) asserts that the runtime is reported as closed when catalog resolution fails, preventing invalid task submissions.

```typescript
// Pattern from task-submission-readiness-main.test.ts
it('reports runtime closed when catalog resolution fails', async () => {
  const readiness = await checkTaskSubmissionReadiness({
    modelId: 'vanished-model-123'
  });
  
  expect(readiness.canSubmit).toBe(false);
  expect(readiness.reason).toBe('catalog_unavailable');
});

```

### Rendering the Unavailable State

The Desktop UI surface, specifically in components like those found in [`apps/desktop/src/renderer/settings/task-catalog-rows.ts`](https://github.com/apache/maka/blob/main/apps/desktop/src/renderer/settings/task-catalog-rows.ts), uses the catalog-unavailable flag to render empty states and warning messages. Users see clear feedback such as "No models are available" or "Capability unavailable" rather than broken interfaces.

## Graceful Degradation for In-Flight Tasks

A critical resilience feature: **if a task is already executing when the catalog changes, the Host continues using the snapshot captured at task start**. This prevents mid-execution crashes due to catalog drift.

New tasks, however, must resolve against the refreshed catalog. Any submission referencing a missing entry is rejected at the validation boundary.

The runtime policy in [`packages/runtime-host/src/protocol/runtime-policy.ts`](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/runtime-policy.ts) (line 165) formalizes this ownership model: the Host maintains the authoritative catalog projection, and clients receive only the current validated view.

```typescript
// Conceptual implementation matching runtime-policy.ts principles
class RuntimeHost {
  private catalogSnapshot: CatalogSnapshot;
  
  async startTask(taskRequest: TaskRequest): Promise<Task> {
    // New tasks validated against fresh catalog
    if (!this.currentCatalog.models[taskRequest.modelId]) {
      throw new CatalogResolutionError(`Model ${taskRequest.modelId} unavailable`);
    }
    
    // Capture snapshot for task lifetime
    const task = new Task(taskRequest, this.captureCatalogSnapshot());
    return task;
  }
  
  private captureCatalogSnapshot(): CatalogSnapshot {
    return structuredClone(this.currentCatalog);
  }
}

```

## Client-Side Detection Patterns

Applications built on Maka can proactively detect missing entries using the runtime client.

### Checking Model Availability

```typescript
// -------------------------------------------------------------
// Load the current model catalog from the Runtime Host
// -------------------------------------------------------------
import { client } from '@maka/core/runtime-client';

async function getModelCatalog() {
  const catalog = await client.loadModelCatalog();
  return catalog; // { models: Record<string, ModelMetadata> }
}

// -------------------------------------------------------------
// Check whether a particular model ID is still present
// -------------------------------------------------------------
async function isModelAvailable(modelId: string): Promise<boolean> {
  const catalog = await getModelCatalog();
  return !!catalog.models?.[modelId];
}

```

### React Component Integration

```typescript
// -------------------------------------------------------------
// Example usage in a UI component
// -------------------------------------------------------------
import { useEffect, useState } from 'react';

function ModelStatus({ modelId }: { modelId: string }) {
  const [available, setAvailable] = useState(true);
  const [checking, setChecking] = useState(true);

  useEffect(() => {
    let cancelled = false;
    isModelAvailable(modelId)
      .then((ok) => {
        if (!cancelled) {
          setAvailable(ok);
          setChecking(false);
        }
      });
    return () => { cancelled = true; };
  }, [modelId]);

  if (checking) return <span>Verifying availability...</span>;
  if (!available) {
    return (
      <span style={{ color: 'red', fontWeight: 'bold' }}>
        ⚠️ Model no longer available — select an alternative
      </span>
    );
  }
  return <span>✓ Model is ready</span>;
}

```

### Server-Side Submission Guard

```typescript
// -------------------------------------------------------------
// Reject task submission if model missing
// -------------------------------------------------------------
import { RuntimeHost } from '@maka/runtime-host';

export async function submitTask(task: TaskRequest): Promise<Task> {
  const catalog = await RuntimeHost.loadModelCatalog();
  
  if (!catalog.models?.[task.modelId]) {
    throw new Error(
      `Cannot submit task – model "${task.modelId}" ` +
      `is not in the catalog. Available models: ${Object.keys(catalog.models).join(', ')}`
    );
  }
  
  return RuntimeHost.startTask(task);
}

```

## Key Implementation Files

Understanding the full lifecycle requires familiarity with these source locations:

- `scripts/sync-model-metadata.mjs` — Builds projected catalog and detects vanished providers during sync operations
- [`packages/runtime/src/__tests__/skills.test.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/__tests__/skills.test.ts) — Validates exclusion of missing skills with diagnostic preservation
- [`packages/runtime-host/src/protocol/runtime-policy.ts`](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/runtime-policy.ts) — Defines Host catalog ownership and client projection rules
- [`apps/desktop/src/main/__tests__/task-submission-readiness-main.test.ts`](https://github.com/apache/maka/blob/main/apps/desktop/src/main/__tests__/task-submission-readiness-main.test.ts) — Verifies runtime closure reporting on catalog failures
- [`apps/desktop/src/renderer/settings/task-catalog-rows.ts`](https://github.com/apache/maka/blob/main/apps/desktop/src/renderer/settings/task-catalog-rows.ts) — UI rendering logic for unavailable catalog states

## Summary

- **Catalog drift detection** occurs during periodic or on-demand refresh cycles in the sync metadata script
- **Missing entries are pruned** from the committed view while diagnostics are retained for audit purposes
- **Active sessions receive catalog-unavailable flags**, triggering graceful UI fallback states
- **In-flight tasks use captured snapshots** to prevent mid-execution failures
- **New task submissions are validated** against the fresh catalog and rejected if referencing vanished entries
- **User experience remains stable** through clear unavailable messaging rather than crashes or undefined behavior

## Frequently Asked Questions

### Does Maka crash if a committed model disappears while a task is running?

No. Maka's Runtime Host captures a **catalog snapshot at task start** and uses that snapshot for the task's entire lifetime. The catalog refresh and drift detection run independently. A task already in flight continues executing with its original model reference even if that model subsequently vanishes from the provider's catalog. New tasks, however, must resolve against the refreshed catalog.

### How can my application detect that a model has become unavailable?

Query the runtime client's `loadModelCatalog()` method and verify that your target `modelId` exists in the returned `models` record. The boolean check `!!catalog.models?.[modelId]` provides a definitive availability signal. For reactive UIs, poll or subscribe to catalog updates and trigger re-renders when availability changes.

### What happens to diagnostic data when a capability is removed?

**Diagnostics are preserved** even though the entry is excluded from the active catalog. The test suite in [`skills.test.ts`](https://github.com/apache/maka/blob/main/skills.test.ts) explicitly verifies this behavior: the drift report captures what went missing and when, supporting audit trails and debugging, while the operational catalog remains clean of invalid references.

### Can users still see removed models in the Maka Desktop interface?

No. The UI components in [`task-catalog-rows.ts`](https://github.com/apache/maka/blob/main/task-catalog-rows.ts) and related renderers check the catalog-unavailable flag. Removed models do not appear in selectable lists. If a previously selected model vanishes while its configuration panel is open, the interface displays a warning such as "Model no longer available" and prompts the user to select an alternative.