Operations API
Git sync, updates, diagnostics, repair, and pipeline operation endpoints.
The git API manages optional automatic commit and sync of the $SIGNET_WORKSPACE/ directory.
Config is loaded from agent.yaml under the git key. Defaults: autoCommit: false, autoSync: false, syncInterval: 300s, remote: origin,
branch: main.
GET /api/git/status
Section titled “GET /api/git/status”Return git status for the agents directory.
Response — output of getGitStatus() including branch, ahead,
behind, dirty, lastCommit.
POST /api/git/pull
Section titled “POST /api/git/pull”Pull from the configured remote and branch.
Response — result of gitPull() including success, output, error.
POST /api/git/push
Section titled “POST /api/git/push”Push the current branch to the configured remote.
Response — result of gitPush().
POST /api/git/sync
Section titled “POST /api/git/sync”Pull then push — equivalent to running both operations in sequence.
Response — result of gitSync().
GET /api/git/config
Section titled “GET /api/git/config”Return the current in-memory git configuration.
Response
{ "enabled": true, "autoCommit": false, "autoSync": false, "syncInterval": 300, "remote": "origin", "branch": "main"}POST /api/git/config
Section titled “POST /api/git/config”Update runtime git configuration. Changes take effect immediately; the sync
timer is restarted if autoSync or syncInterval changes.
Request body (all fields optional)
{ "autoCommit": true, "autoSync": true, "syncInterval": 600, "remote": "origin", "branch": "main"}Response
{ "success": true, "config": { ... } }Update
Section titled “Update”The update system checks GitHub releases and the npm registry, then optionally auto-installs using the detected package manager.
GET /api/update/check
Section titled “GET /api/update/check”Check for a newer version. Results are cached for 1 hour unless ?force=true
is passed.
Query parameters
| Parameter | Description |
|---|---|
force |
true — bypass 1-hour cache |
Response
{ "currentVersion": "0.124.5", "latestVersion": "0.124.4", "updateAvailable": true, "releaseUrl": "https://github.com/Signet-AI/signetai/releases/tag/v0.124.4", "releaseNotes": "...", "publishedAt": "2026-02-20T12:00:00Z", "restartRequired": false, "pendingVersion": null, "cached": false, "checkedAt": "2026-02-21T10:00:00.000Z"}GET /api/update/config
Section titled “GET /api/update/config”Return current update configuration and runtime state.
Response
{ "autoInstall": false, "checkInterval": 21600, "channel": "stable", "minInterval": 300, "maxInterval": 604800, "pendingRestartVersion": null, "lastAutoUpdateAt": null, "lastAutoUpdateError": null, "updateInProgress": false}POST /api/update/config
Section titled “POST /api/update/config”Modify auto-update settings. Changes are persisted to agent.yaml.
Request body (all fields optional)
{ "autoInstall": true, "checkInterval": 43200, "channel": "nightly"}checkInterval must be between 300 and 604800 seconds. channel must be stable or nightly.
Response
{ "success": true, "config": { "autoInstall": true, "checkInterval": 43200, "channel": "nightly" }, "persisted": true, "pendingRestartVersion": null, "lastAutoUpdateAt": null, "lastAutoUpdateError": null}POST /api/update/run
Section titled “POST /api/update/run”Install the latest version immediately. The daemon updates the executable that is actually running: direct native installs download the matching verified release binary, while npm, Bun, pnpm, and Yarn wrapper installs retain their owning package manager. A daemon restart is required to activate the update.
Response
{ "success": true, "message": "Update installed. Restart daemon to apply.", "output": "...", "installedVersion": "0.110.0", "restartRequired": true, "installMethod": "native", "activeExecutablePath": "/home/user/.local/bin/signet", "activeExecutableVerified": true, "observedVersion": "0.110.0"}Failures return success: false, restartRequired: false,
and a stable errorCode such as manifest_invalid, checksum_mismatch,
install_failed, or verification_failed. activeExecutableVerified is true
only when the active path reports the selected version exactly, and
observedVersion is present whenever that path returned a valid version. If
already up to date, the route returns success: true with a message indicating
no update is needed.
Diagnostics
Section titled “Diagnostics”Requires diagnostics permission.
GET /api/diagnostics
Section titled “GET /api/diagnostics”Full diagnostic report across all domains. Includes a composite health score
derived from queue, storage, index, provider, mutation, duplicate, connector,
update, and graph health. storage.dbSizeBytes is computed from SQLite page
metadata. When graph is enabled, graph.status is included in composite status
so a flatlined knowledge graph cannot be hidden behind otherwise healthy
storage and index signals. Dreaming is the sole automatic semantic writer;
graph diagnostics report graph health without exposing a retired extractor gate.
When agentId is supplied in a scoped deployment, it must match the
authenticated agent scope; the embedded workloads snapshot is for that
resolved agent.
Response — a multi-domain report object. Domains include queue,
storage, index, provider, mutation, duplicate, connector, update,
graph, openclaw, composite, and workloads. The composite field looks like:
{ "score": 0.95, "status": "healthy" }GET /api/diagnostics/:domain
Section titled “GET /api/diagnostics/:domain”Diagnostic data for a single domain. Known domains include queue, storage,
index, provider, mutation, duplicate, connector, update, graph,
openclaw, and composite.
Returns 400 for unknown domains.
GET /api/diagnostics/transcripts
Section titled “GET /api/diagnostics/transcripts”Scoped transcript capture diagnostics. Returns durable capture queue counts, session transcript row age metadata, manifest/artifact counts, pending or failed summary counts, missing transcript/summary artifact counts, and transcript audit log metadata. Agent-scoped requests do not expose legacy flat audit log counts because those filenames are not agent-scoped.
GET /api/diagnostics/workloads
Section titled “GET /api/diagnostics/workloads”Returns bounded in-flight workload pressure for one resolved agent. The
inference snapshot covers background routed work and Pi agent sessions; the
MCP snapshot covers stateless Streamable HTTP requests. Counts are held in
memory and ages are calculated from admission time, so this endpoint does not
scan durable queue tables. agentId may be supplied as a query parameter or
x-signet-agent-id header; scoped deployments reject requests for another
agent.
The response contains agentId, inference (active, agentSessions,
oldestAgeMs, oldestAgentSessionAgeMs, and per-operation byOperation), and
mcp (inFlight, oldestAgeMs, and maxInFlight). MCP requests are admitted
at most 8 at a time.
GET /api/diagnostics/memory-content-safety
Section titled “GET /api/diagnostics/memory-content-safety”Return bounded, agent-scoped content-safety ledger diagnostics. The response
includes counts by source kind and status plus source identifiers, reason codes,
policy version, and scan time. It does not return raw content; use an
authorized GET /api/memory/:id or source inspection endpoint when the
retained evidence itself must be audited.
Query parameters are agentId, status (clean, tainted, or blocked),
sourceKind (memory, artifact, transcript, summary, or source_chunk),
limit (1–200, default 100), and offset (0–100000, default 0).
GET /api/diagnostics/database/schema
Section titled “GET /api/diagnostics/database/schema”Read-only SQLite schema explorer data for the dashboard database table view. Returns live table metadata grouped by conceptual area, with row counts, columns, indexes, foreign keys, and whether sample rows are available.
Response
{ "generatedAt": "2026-05-15T12:00:00.000Z", "groups": { "core": 8, "provenance": 6, "runtime": 12, "internal": 3, "other": 1 }, "tables": [ { "name": "entities", "group": "core", "kind": "table", "rowCount": 42, "sampleAllowed": true, "columns": [ { "cid": 0, "name": "id", "type": "TEXT", "notNull": false, "defaultValue": null, "primaryKey": true } ], "indexes": [], "foreignKeys": [], "sql": "CREATE TABLE entities (...)" } ]}GET /api/diagnostics/database/tables/:table/sample
Section titled “GET /api/diagnostics/database/tables/:table/sample”Returns a bounded read-only sample for a validated table name. The daemon
derives valid table names from SQLite metadata before constructing SQL.
Internal index and virtual tables can return 400 with an explanatory error.
Query parameters:
| Name | Default | Notes |
|---|---|---|
limit |
25 |
Clamped to 1..100. |
offset |
0 |
Clamped to non-negative values. |
Response
{ "table": "entities", "columns": ["id", "name", "entity_type"], "rows": [{ "id": "entity-1", "name": "Signet", "entity_type": "system" }], "limit": 25, "offset": 0, "rowCount": 42, "hasMore": true}Repair
Section titled “Repair”Administrative repair operations. All require admin permission. Operations
are rate-limited internally by the repair limiter and return 429 when the
limit is exceeded.
POST /api/repair/requeue-dead
Section titled “POST /api/repair/requeue-dead”Requeue extraction jobs stuck in a terminal-failed state. Typically used after resolving a pipeline configuration issue.
Response
{ "action": "requeueDeadJobs", "success": true, "affected": 12, "message": "..." }POST /api/repair/release-leases
Section titled “POST /api/repair/release-leases”Release stale pipeline job leases that have exceeded their timeout. Run this
if pipeline workers crashed and left jobs locked. Stale jobs that still have
remaining retries are returned to pending. Stale jobs that have already
reached max_attempts are moved to dead instead of being requeued again.
Response
{ "action": "releaseStaleLeases", "success": true, "affected": 3, "message": "released 2 stale lease(s) back to pending and dead-lettered 1 exhausted job(s)"}POST /api/repair/check-fts
Section titled “POST /api/repair/check-fts”Check FTS5 index consistency against the memories table and detect legacy
tokenizer drift. Optionally repair mismatches by rebuilding the index or
recreating memories_fts with the canonical unicode61 tokenizer.
Request body (optional)
{ "repair": true }Response
{ "action": "checkFtsConsistency", "success": true, "affected": 0, "message": "..." }POST /api/repair/retention-sweep
Section titled “POST /api/repair/retention-sweep”Trigger a bounded retention cleanup sweep immediately. This purges expired
tombstones, old history rows, expired completed/dead jobs, orphaned graph links,
and orphaned embeddings without waiting for the retention worker interval.
Requires admin permission.
Response
{ "action": "retention_sweep", "success": true, "affected": 3, "message": "retention sweep completed; 3 row(s) purged", "details": { "tombstones": 1, "history": 1, "completedJobs": 1 }}GET /api/repair/embedding-gaps
Section titled “GET /api/repair/embedding-gaps”Returns the count of memories that are missing vector embeddings.
Requires admin permission.
Response
{ "unembedded": 42, "total": 1200, "coverage": "96.5%"}POST /api/repair/re-embed
Section titled “POST /api/repair/re-embed”Batch re-embeds memories that are missing vector embeddings. Processes at most
20 memories per call, subject to the durable cooldown, hourly budget, byte
budget, and run-time budget. Requires admin permission. Rate-limited — returns
429 when the limit is exceeded.
A full sweep uses fullSweep: true and returns an operationId. Repeat the
request with that operation ID after the reported cooldown to resume the next
bounded batch. Checkpoint state survives daemon restarts. Provider failures,
request cancellation, and budget exhaustion leave the operation resumable;
profile changes or cross-agent hash conflicts fail the operation explicitly.
Request body
{ "batchSize": 20, "fullSweep": true, "operationId": "embedding-repair-...", "maxVectorBytes": 4194304, "runBudgetMs": 30000, "dryRun": false}batchSize defaults to 20, the server maximum. When supplied, it must be a
positive integer. maxVectorBytes and runBudgetMs are bounded by server-side
ceilings. dryRun: true reports what would be embedded without calling the
embedding provider.
Response
{ "action": "reembedMissingMemories", "success": true, "affected": 20, "message": "re-embedded 20 of 20 memories in one bounded batch (22 still missing)", "details": { "operationId": "embedding-repair-...", "status": "running", "remaining": 22, "batches": 1 }}POST /api/repair/re-embed-migration
Section titled “POST /api/repair/re-embed-migration”Re-embeds a bounded batch of active memories whose stored model or vector
dimensions differ from the configured embedding target. Set all: true to
force a bounded batch even when metadata already matches. Requires admin
permission. Existing vectors remain in place until a replacement vector has
been fetched and validated.
Request body
{ "batchSize": 50, "dryRun": true, "all": false, "agentId": "default"}dryRun: true reports the full matching count, source model/dimension labels,
target provider/model/dimensions, estimated batches, and whether a dimension
change requires rebuilding the vector index. Provider identity is not present
in historical embedding metadata and is reported as not-recorded.
The request is scoped to agentId; when omitted it uses the daemon’s active
agent.
Response
{ "action": "reembedModelMigration", "success": true, "affected": 0, "totalMatching": 120, "details": { "selected": 120, "selectedThisBatch": 50, "target": { "provider": "ollama", "model": "nomic-embed-text", "dimensions": 768 }, "estimatedBatches": 3, "vectorIndexRebuildRequired": false }}POST /api/repair/clean-orphans
Section titled “POST /api/repair/clean-orphans”Remove embedding rows that reference memories which no longer exist. The
operation is scoped to the resolved agentId and runs through a durable,
keyset-paginated owner checkpoint. Repeat the request until status is
complete; a client disconnect or owner restart resumes from the same
checkpoint. It only removes derived vector rows whose canonical embedding is
owned by the same scope; vector rows with no canonical owner are retained.
Global reconciliation is not accepted by this endpoint.
Rate-limited. Requires admin permission.
Request body (optional)
{ "agentId": "default", "batchSize": 50, "maxVectorBytes": 262144, "maxBatches": 20}The server hard-caps every owner job at 50 rows, 256 KiB of vector payload, 2 seconds, and 100 estimated work units. Request values can lower those ceilings but cannot raise them.
Response
{ "action": "cleanOrphanedEmbeddings", "success": true, "affected": 12, "operation": "clean-orphans", "agentId": "default", "checkpointId": "vector-repair-...", "phase": "complete", "status": "complete", "processed": 12, "skipped": 0, "failed": 0, "remaining": 0, "remainingStatus": "none", "message": "cleaned orphaned embeddings; processed 12, no work remaining; checkpoint vector-repair-..."}POST /api/repair/resync-vec
Section titled “POST /api/repair/resync-vec”Reconcile the derived vec_embeddings index with canonical embeddings for
one resolved agent by inserting canonical vectors that are missing from the
index. A scoped request does not remove derived rows that have no canonical
embedding: those rows have no provable agent owner and are retained rather
than risking cross-agent deletion. Each owner transaction is a bounded page
and advances the durable checkpoint atomically with its mutations and semantic
repair audit. Repeat the request while status is running.
The same hard server ceilings apply: 50 rows, 256 KiB of vector payload, a
2-second owner deadline, and 100 estimated work units per job. Malformed or
oversized canonical vectors beyond the hard 256 KiB ceiling are quarantined
when the quarantine table is available and reported as skipped; a valid
vector that does not fit the caller’s lower per-batch byte budget is deferred
without quarantine. Retryable owner write failures retain the cursor and are
reported as failed.
Request body (optional)
{ "agentId": "default", "batchSize": 50, "maxVectorBytes": 262144, "maxBatches": 20}Response
The response includes processed, skipped, failed, remaining,
remainingStatus, checkpointId, phase, and status in addition to the usual repair action
fields. remaining is a bounded presence marker: 0 means no matching work
remains and 1 means the owner found some work; it is not an exact count.
status: "running" is a successful bounded-progress response at HTTP 200 and
must be resumed with the same resolved scope. agentId is always the resolved
scope; allAgents and scope: "all" are rejected rather than broadening the
operation.
GET /api/repair/dedup-stats
Section titled “GET /api/repair/dedup-stats”Returns statistics on potential duplicate memories (by content hash).
Requires admin permission.
Response — object with duplicate counts and affected memory IDs.
POST /api/repair/deduplicate
Section titled “POST /api/repair/deduplicate”Deduplicate memories by content hash and optionally by semantic similarity.
Rate-limited. Requires admin permission.
Request body
{ "batchSize": 50, "dryRun": false, "semanticEnabled": false, "semanticThreshold": 0.95}All fields are optional. dryRun: true reports what would be deduplicated
without making changes. semanticEnabled adds vector-similarity dedup on
top of hash-based dedup.
Response
{ "action": "deduplicateMemories", "success": true, "affected": 7, "message": "deduplicated 7 memories"}POST /api/repair/relink-entities
Section titled “POST /api/repair/relink-entities”Attach unlinked memories to existing entities whose names appear in the memory content. The operation is agent-scoped and never creates new entities.
Request body
{ "agentId": "default", "batchSize": 500, "dryRun": true}batchSize defaults to and is capped at 500. The default remains
dryRun: false for compatibility. With dryRun: true, Signet performs the
same entity matching without changing mention rows or entity counters.
remaining is the current persisted count, while projectedRemaining is the
count that would remain if the preview were applied.
Dry-run response
{ "action": "relink-entities", "dryRun": true, "processed": 500, "linked": 398, "entities": 398, "aspects": 0, "attributes": 0, "remaining": 7267, "projectedRemaining": 6869, "message": "dry run: 398 link(s) would be added across 398 memories; 6869 would remain unlinked"}POST /api/repair/prune-generic-entities
Section titled “POST /api/repair/prune-generic-entities”Remove non-concrete, unpinned entities for the resolved agent. Scanning uses a bounded inspection budget and can return a cursor for a later request.
Request body
{ "agentId": "default", "candidateLimit": 100, "inspectionLimit": 1000, "cursor": { "updatedAt": "2026-05-11T18:00:00.000Z", "id": "ent-123" }, "dryRun": true}candidateLimit defaults to 100 and is capped at 500. It limits matching
entities. inspectionLimit defaults to 1000 and is capped at 5000; it
limits all inspected entities independently of matches. cursor is optional
and resumes after the supplied (updatedAt, id) position. Dry-run is enabled
by default. Each request also has a server-owned scan time budget; expiration
returns a partial response with the cursor. The response reason identifies
whether scanning stopped at a limit, deadline, cancellation, or system pressure.
Partial response
{ "action": "pruneGenericEntities", "success": true, "affected": 0, "message": "dry-run: would delete 0 generic/non-concrete entities; partial scan after 1000 inspected row(s), resume with cursor", "details": { "status": "partial", "complete": false, "candidateLimit": 100, "inspectionLimit": 1000, "inspected": 1000, "matched": 0, "remaining": "unknown", "reason": "inspection_limit", "cursor": { "updatedAt": "2026-05-11T18:00:00.000Z", "id": "ent-123" } }}Pipeline
Section titled “Pipeline”GET /api/pipeline/status
Section titled “GET /api/pipeline/status”Composite pipeline status snapshot for dashboard visualization. Returns worker status, database maintenance state, job queue counts (memory and summary), diagnostics, latency histograms, error summary, and the current pipeline mode.
The workers.document entry includes inFlight and maxInFlight counts for
the shared document-ingest admission budget. inFlight counts jobs that have
been leased and are still processing; the worker does not lease another job
when this budget is full.
Known mode values: controlled-write, shadow, frozen, paused,
disabled.
Response
{ "workers": { "document": { "running": true, "inFlight": 1, "maxInFlight": 2 } }, "databaseMaintenance": { "vacuumConversion": { "state": "pending", "attempts": 0, "maxAttempts": 3, "requestedAt": "2026-08-11T23:00:00.000Z", "startedAt": null, "completedAt": null, "updatedAt": "2026-08-11T23:00:00.000Z", "lastError": null } }, "queues": { "memory": { "pending": 3, "leased": 1, "completed": 200, "failed": 0, "dead": 0 }, "summary": { "pending": 0, "leased": 0, "completed": 5, "failed": 0, "dead": 0 } }, "diagnostics": { ... }, "latency": { ... }, "errorSummary": { ... }, "mode": "controlled-write"}Mode is one of: disabled, frozen, shadow, paused, controlled-write.
When DB-owner maintenance is unavailable before startup completes, this endpoint returns 503 instead of reading SQLite from the request process. During owner shutdown, queue counts are intentionally returned as empty maps while the owner drains.
databaseMaintenance.vacuumConversion reports the durable legacy SQLite
conversion state. Existing databases enter pending after migrations and are
converted by a single-flight worker after readiness. A restart changes an
interrupted running conversion back to pending; failures retain
lastError and retry only within the reported attempt budget. Fresh or already
converted databases report not_required or completed.
POST /api/pipeline/pause
Section titled “POST /api/pipeline/pause”Pause the extraction runtime in-place without restarting the daemon.
Requires admin permission and uses the admin rate limit bucket.
Returns 409 if another pause/resume transition is already running.
Response
{ "success": true, "changed": true, "paused": true, "file": "/home/user/.agents/agent.yaml", "mode": "paused", "quiescence": { "activeAtStart": 1, "aborted": 1, "remaining": 0, "timedOut": false }}After a successful pause, background extraction, session synthesis (including
dreaming), and repair inference admission is closed. Active provider calls are
aborted and boundedly drained before this response. remaining: 0 confirms
that no tracked background inference call remains active.
POST /api/pipeline/resume
Section titled “POST /api/pipeline/resume”Resume the extraction runtime in-place without restarting the daemon.
Requires admin permission and uses the admin rate limit bucket.
Response
{ "success": true, "changed": true, "paused": false, "file": "/home/user/.agents/agent.yaml", "mode": "controlled-write"}changed is false when the persisted pause flag already matches the
requested state.

