Skip to content

Maintenance tools

kb_status

Input: none.

Output: one cached snapshot with single_workspace/single_engagement scope, bind scope, effective HTTP allowed_hosts (an empty list for stdio), authentication: "none", database/WAL/retention/index samples, process-local queues, and fixed capabilities. Samples explicitly report availability, cache age, and staleness. Status is SQL-free at call time and cannot measure external reader age.

database.sample.derived_storage reports SQLite page-allocation bytes separately for decoded text projections and their lookup indexes, FTS shadow tables/indexes, and property projections/indexes. These include page slack; they exclude canonical graph records, raw evidence files, free pages and WAL. They are not filesystem allocated-block counts or a raw-to-index expansion ratio.

Cheap database counters are sampled at startup and every 30 seconds. A separate reader task starts the derived-storage scan without delaying the initial counters, then samples no more often than every 300 seconds. It streams selected B-tree pages under a one-second absolute budget and checks cancellation between pages. Missing dbstat support leaves a never-measured cache unavailable and stale, with DBSTAT_UNAVAILABLE as its reason and last error and null timestamps/bytes. After a successful scan, later lack of dbstat keeps the complete prior bytes and timestamp available but stale, with DBSTAT_UNAVAILABLE as the last error. Its own cached_at, cache_age, stale, and last_error describe the byte totals independently: they become stale after 600 seconds or a failed attempt. A failure preserves the complete last-known byte totals without staling a successful cheap counter sample. Native page I/O has no hard latency bound.

WAL diagnostics include maintenance_alive, maintenance_error, and maintenance_failed_permanently. A permanent local maintenance fault rejects product operations with its nonretryable error category; status, control, and coordinated shutdown remain available. Transient failures retry at a bounded cadence and clear after a newer successful measurement. Physical-high assessment is a process-local cached observation, so peers can briefly display different phases; shared measurements and each process's admission checks still protect the workspace independently.

A retired reader reduces local capacity while healthy owners continue. An exhausted read lane or failed writer reports a stable storage error; ordinary queue saturation remains retryable BUSY.

Errors: only bounded internal/configuration failure at the wrapper; stale or unavailable sampled state normally remains successful structured data.

kb_status.background_error contains the latest sanitized background-job failure, or null when no failure has been cached. It is an attention diagnostic, not a live database check or proof of current job state. Retention diagnostics have their own retention.last_error and needs_attention; retention failures do not replace background_error. They remain visible until a complete successful scan finds no invalid metadata or pending purge work. Maintenance health is separate from WAL pressure: a fresh valid sample clears a transient error even when pressure remains. Permanent maintenance failure stays latched.

kb_delete

Input: kind, 1–100 unique IDs, and cascade defaulting to false.

Output: durable delete job state with inline completed or accepted, deleted IDs, attempts/progress, and blocker/attention metadata.

Errors: NOT_FOUND with all missing IDs rejects the whole batch; CONFLICT for dependencies or repeated/pending delete, with bounded blocker, owner job, and intent time; BUSY, LIMIT, or storage errors. Once intent commits it cannot be cancelled. cascade: true removes incident relations and links while preserving neighboring nodes and unselected evidence blobs.

Deleting a rejected node is an explicit purge: it lifts the block on re-creating its identity, and on creating subdomains under a rejected domain. A rejected node keeps its evidence links, so it needs cascade: true. Deleting evidence that is the last ready link of a node holding an ownership or authorization claim returns CONFLICT: LAST_CLAIM_EVIDENCE, and the blocker names that node; link other evidence first, or withdraw the claim.

kb_jobs

Input: action defaults to list. List accepts optional state, limit 20, and cursor. get, cancel, and retry require only job_id and reject list fields.

Output: list returns jobs plus next_cursor; control/get returns one durable job record. A retry resumes eligible failed/cancelled work from its supported checkpoint; copied evidence restarts at byte 0.

Cancelling an already terminal non-delete job with valid metadata is idempotent and returns its unchanged state. Delete intent and purge protection still reject cancellation. attempts counts durable claims/steps, including normal multi-step work, pressure deferrals and lease takeover; it is not a count of user retries.

Retention preserves canonical evidence, sources and links. A published blob without a canonical owner is cleaned only under its digest lock after proving that no nonpurging job can still use it. Uncertain ownership retains the job's locator and reports attention; malformed ownership metadata can delay orphan blob cleanup while unrelated metadata and staging cleanup continue.

Malformed job metadata is isolated as a failed job with JOB_METADATA_INVALID before workers acquire a new lease. Its raw metadata and trusted blob locator remain protected, and get/list report needs_attention and retention_protected. Cancel and retry reject corrupt metadata with CONFLICT: JOB_METADATA_INVALID without changing it. Retention also marks discovered corruption with JOB_METADATA_INVALID, preserving raw metadata, terminal state, counters and file ownership. Repair requires reviewed offline correction of the metadata and its invalid marker before normal processing resumes. Other jobs continue processing.

Retention counts are targets: protected or corrupt rows can leave the count above the configured target. Count-triggered scans wait at least 30 seconds after a complete sweep before retrying, even when other jobs complete; bounded continuation batches, startup/forced scans and age-triggered maintenance remain available. This cooldown and the diagnostic cache are process-local: each MCP process tracks its own scans. The delay does not block cancellation, new ingest or unrelated cleanup.

Errors: INVALID for action/field combinations; NOT_FOUND after normal retention pruning; CONFLICT for ineligible cancellation/retry, including immutable pending delete intent and a row already being purged; BUSY, LIMIT, or storage errors. Required failed delete jobs remain retention-protected.

kb_reindex

Input: kind and exactly one of 1–100 unique ids or all: true. A media_type or encoding correction is allowed only with one evidence ID.

Output: accepted/completed durable reindex job with state, progress, reused, coverage_incomplete, generation_changed_count, index_busy_count, and bounded sample IDs. A matching active full pass can be reused.

Errors: INVALID for ambiguous selection/override; NOT_FOUND for missing IDs; CONFLICT for another incompatible full pass or pending deletion; INDEX_ERROR, BUSY, LIMIT, or storage errors. Reindex rebuilds derived state from current canonical records and never resets canonical data. Full-pass job skip coverage is distinct from kb_search.coverage, which describes the live workspace when that search runs.

Operational WAL retry and safe copy/upgrade procedures are in Workspace and operations.