Files
spacedrive/docs/core/ops.mdx
T
Jamie Pine 2d380fd264 Move docs to Fumadocs and rewrite the core docs
Replaces the Mintlify setup (mint.json, docs.json, snippets) with a
standalone Fumadocs app in docs/: Next.js app router, meta.json nav per
section, its own bun install. Run with `just dev-docs`.

Content pass alongside the migration: core architecture, data model,
CLI, and networking pages rewritten around the daemon/source-store/
library split, new product-direction.mdx defining the product boundary,
new drive-catalog plan, and the physical-drives plan updated to
reference it. Whitepaper page retired.
2026-09-15 00:59:30 -07:00

152 lines
4.0 KiB
Plaintext

---
title: Operations
description: Define one typed action or query for every client
sidebarTitle: Operations
---
Operations are the public behavior of Spacedrive core. Define an operation once
in Rust, register it, and consume the same input and output from local IPC, web,
CLI, peer networking, generated clients, skills, and MCP.
## Queries and actions
- A **query** reads state without hidden mutation.
- An **action** requests a state change.
Both can be core-scoped or library-scoped. Core operations handle daemon and
library lifecycle. Library operations handle sources, records, organization,
jobs, and policy.
## Module shape
Keep each feature under its domain:
~~~text
core/src/ops/files/share/
├── mod.rs
├── input.rs
├── output.rs
├── action.rs
└── job.rs
~~~
Small features can use fewer files. The boundary matters more than the exact
layout: inputs and outputs are public types, while filesystem and database
details remain behind the handler.
## Registration
Use registration macros. Never implement the wire trait manually.
~~~rust
pub struct FileShareAction;
crate::register_library_action!(FileShareAction, "files.share");
impl Action for FileShareAction {
type Input = ShareFileInput;
type Output = ShareFileOutput;
async fn run(
input: Self::Input,
ctx: &ActionContext,
) -> Result<Self::Output, ActionError> {
// Validate scope, commit state, and return structured output.
}
}
~~~
Available macros register core or library queries and actions into the compile
time inventory.
## Input and output
Public types:
- derive serialization and Specta type metadata;
- use stable IDs instead of database row numbers;
- represent unavailable and partial state explicitly;
- avoid leaking provider-specific secrets;
- remain backward-compatible within a protocol version.
After changing a public Rust type, regenerate TypeScript:
~~~bash
cargo run --bin generate_typescript_types
~~~
Frontend code imports those generated types. It does not redefine or cast them
away.
## Action lifecycle
An action performs only enough synchronous work to validate the request and
commit a bounded state change. Long work dispatches a durable job.
Risky mutations follow:
1. **Preview** exact targets, conflicts, cost, and protection consequences.
2. **Commit** an immutable plan or bounded state change.
3. **Execute** durable work with progress and cancellation.
4. **Verify** effects against the origin and content evidence.
5. **Report** structured output and durable logs.
Not every action needs a preview. Creating a tag can commit directly. Deleting
the last verified copy cannot.
## Context and authorization
Handlers receive a context that identifies:
- authenticated session or peer;
- selected library;
- granted sources and subtrees;
- allowed query and mutation classes;
- request and trace IDs;
- access to approved services.
Operations check capabilities before resolving sensitive data. A handler must
not infer permission from the fact that a path exists.
## Errors
Return typed errors for invalid input, missing identity, offline origins,
permission denial, conflicts, provider failure, and verification failure.
Logs explain diagnostics. They are not the API response.
## Events
Publish change events after the durable transaction commits. Clients that react
to an event must be able to query the new state immediately.
Large operations emit scoped invalidation or batch events instead of one event
per record.
## Generic clients
The CLI can invoke a registered operation by name:
~~~bash
sd-cli op sources.list --json '{}'
~~~
Skills and MCP use the same names and schemas. They do not translate arbitrary
text into an unregistered shell command.
## Tests
Operation tests cover:
- input validation;
- authorization at every scope;
- typed error shape;
- idempotency or deduplication;
- transaction rollback;
- job dispatch and final output;
- generated client compatibility;
- event ordering.
See [API](/core/api) for transports and [Jobs](/core/jobs) for durable
execution.