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.