Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
8c493c2
feat: Add Drasi Control UI with real-time SSE updates
agentofreality Feb 23, 2026
98e09e0
feat: add source data push proxy, expandable canvas nodes, and canvas…
agentofreality Feb 24, 2026
a72687e
Fix SSE connection exhaustion causing slow UI interactions
agentofreality Feb 24, 2026
6697e1f
Fix nodes visibly shrinking on initial page load
agentofreality Feb 24, 2026
b19163b
Add Drasi logo to Admin UI and rename from 'Drasi Control' to 'Drasi …
agentofreality Feb 24, 2026
62977fd
Reorganize canvas lock controls and add multi-select node lock toggle
agentofreality Feb 24, 2026
4b3b635
Replace bottom event bar with slide-out activity panel and update fav…
agentofreality Feb 24, 2026
559b78d
feat(ui): add light/dark theme toggle with localStorage persistence
agentofreality Feb 24, 2026
3a18dfa
Fix smooth vertical displacement of nodes during expand/collapse
agentofreality Feb 24, 2026
6b5805d
Add solution templates feature with catalog UI and validation-first d…
agentofreality Feb 25, 2026
ed65283
fix(ui): standardize collapsed node heights across all component types
agentofreality Feb 25, 2026
ad53db1
fix(ui): animate edges only when both connected nodes are running
agentofreality Feb 25, 2026
df288b7
Add live query results to UI and fix solution template label
agentofreality Feb 25, 2026
e5c5325
Add comprehensive solution template tests with E2E data flow validation
agentofreality Feb 25, 2026
0c4c1b0
Improve light theme contrast and fix IoT template query label
agentofreality Feb 25, 2026
b6938a3
Redesign node cards with compact toolbar and improved UX
agentofreality Feb 25, 2026
ff7b213
UI: Redesign inspector panels and canvas controls
agentofreality Feb 26, 2026
4e39acd
UI: Update component color scheme to Drasi conventions
agentofreality Feb 26, 2026
9176415
UI: Match inspector panel icons to canvas node icons
agentofreality Feb 26, 2026
f0bd624
Add .vscode to .gitignore
agentofreality Feb 26, 2026
4233a48
Remove .vscode from git tracking
agentofreality Feb 26, 2026
b507ea7
UI: Clean up persisted node state on deletion
agentofreality Feb 26, 2026
5516c99
UI: Show query language type on query nodes
agentofreality Feb 26, 2026
71b2026
UI: Add auto-layout button to canvas controls
agentofreality Feb 26, 2026
1e03fe5
UI: Widen instance selector for GUID display
agentofreality Feb 26, 2026
8502ded
UI: Fit view after auto-layout
agentofreality Feb 26, 2026
0aa2312
feat: Add instance management features (clone, create with template, …
agentofreality Feb 26, 2026
476c373
fix: Add instanceId to reaction node data and fix clippy warnings
agentofreality Feb 26, 2026
9d85878
refactor(ui): Improve Query inspector panel layout
agentofreality Feb 26, 2026
df06cd5
feat(ui): Add interactive controls to inspector Data Flow sections
agentofreality Feb 26, 2026
45444f5
feat: make web UI optional via config and CLI flags
agentofreality Feb 26, 2026
3aa1c2d
docs: Comprehensive README rewrite for newcomers
agentofreality Feb 26, 2026
432f946
fix: correct temperature threshold in IoT solution template
agentofreality Feb 26, 2026
bcf5c9c
fix(ui): use consistent colors for start/stop buttons in DATA FLOW se…
agentofreality Feb 26, 2026
14f1da1
fix(ui): auto-arrange uses actual node dimensions for proper spacing
agentofreality Feb 26, 2026
4e2d0e8
feat(ui): Add SolutionInstanceWizard for template-based instance crea…
agentofreality Mar 2, 2026
c1483b4
feat(trading): Add sector performance aggregation with real-time updates
agentofreality Mar 5, 2026
d5bad45
feat(trading): Make watchlist data-driven with three-way join
agentofreality Mar 5, 2026
d89f13e
feat(trading): Add CRUD UI for watchlist and portfolio management
agentofreality Mar 5, 2026
a1deacc
refactor(trading): Extract queries to separate presentation-friendly …
agentofreality Mar 5, 2026
d7b9250
feat(trading): refactor position management with new dialog component
agentofreality Mar 5, 2026
dfb49ec
refactor(trading): Extract reusable QueryTable component and shared u…
agentofreality Mar 5, 2026
a98c57b
refactor(trading): Extract shared UI components to reduce duplication
agentofreality Mar 5, 2026
867c46a
feat(trading-ui): Reorganize dashboard panel layout
agentofreality Mar 5, 2026
102e72a
feat(trading-ui): Add code viewer dialog for presentations
agentofreality Mar 5, 2026
6ffbec2
fix(trading): only delete SSE reaction if app created it
agentofreality Mar 5, 2026
a640a90
feat(trading): Add limit orders with Drasi future function demo
agentofreality Mar 5, 2026
f72aa29
feat(trading-app): fetch query definition from Drasi Server and add U…
agentofreality Mar 5, 2026
c30fff3
refactor(trading-app): use camelCase Cypher aliases, remove runtime t…
agentofreality Mar 5, 2026
873c58a
fix(trading-app): portfolio summary not updating due to unstable map key
agentofreality Mar 5, 2026
3fc865b
feat(trading-app): add expandable tables for presentations
agentofreality Mar 6, 2026
ab58bc5
fix(trading-app): wrap DECIMAL fields in toFloat() for CDC compatibility
agentofreality Mar 6, 2026
2059b94
feat(trading): duration-based trueFor queries and order management fixes
agentofreality Mar 6, 2026
210e789
feat(trading): add scriptfile bootstrap for price-feed source
agentofreality Mar 6, 2026
1312ac3
fix(trading-app): fix layout jitter and UI polish
agentofreality Mar 6, 2026
5447585
Add Broker Panel UI and improve trading demo cleanup
agentofreality Mar 7, 2026
0991d0a
Add Cypher/GQL syntax highlighting to Query Inspector
agentofreality Mar 7, 2026
01974b4
Reduce unnecessary re-renders with React.memo and useMemo
agentofreality Mar 7, 2026
61d73cc
Optimize canvas re-renders, query streaming, and node internals
agentofreality Mar 7, 2026
d4ff8f4
Memoize inspector props, reduce animation overhead, fix MATCH highlig…
agentofreality Mar 7, 2026
d624183
fix: update for drasi-lib 0.4.x API changes and add UI build support
Mar 19, 2026
22400d9
Merge ui branch into main with conflict resolution and test fixes
agentofreality Mar 19, 2026
ac4784a
fix: add local plugin build workflow and fix trading demo segfault
agentofreality Mar 22, 2026
05ab0ca
feat: full plugin-aware config validation for validate command
agentofreality Mar 24, 2026
2871622
fix(ui): correct canvas node displacement on expand/collapse
agentofreality Mar 25, 2026
28235ea
Working on UI Canvas Node expansion.
agentofreality Mar 25, 2026
d485b19
refactor(ui): use fixed target heights for node layout displacement
agentofreality Mar 25, 2026
2c25d6e
fix: replace unwrap() with expect() in validate CLI test
agentofreality Mar 26, 2026
24dff39
feat: add commit-staged skill for project
agentofreality Mar 26, 2026
a845e24
feat: implement runtime plugin management system
agentofreality Mar 26, 2026
b25565d
feat: local dir plugin source + init wizard select-or-install flow
agentofreality Mar 27, 2026
78f9417
refactor: improve init wizard prompts and settings
agentofreality Mar 27, 2026
aac127d
feat: add left panel sidebar UI with 6 tabbed sections
agentofreality Mar 27, 2026
b15c626
fix: auto-hide left panel on canvas click when not pinned
agentofreality Mar 27, 2026
04fd712
refactor: replace health polling with SSE connection state
agentofreality Mar 27, 2026
725af02
fix: derive component catalog from installed plugins only
agentofreality Mar 27, 2026
f490b91
feat: schema-driven config editor + OpenAPI plugin annotations
agentofreality Mar 27, 2026
192f4b7
rename build-test-plugins to build-local-test-plugins
agentofreality Mar 28, 2026
1fa8988
fix: improve UI error visibility, SSE event handling, and Monaco setup
agentofreality Mar 31, 2026
92fba14
feat(ui): sort sidebar panel items alphabetically
agentofreality Mar 31, 2026
9c07a24
fix(ui): set queryLanguage based on selected query type
agentofreality Mar 31, 2026
d2c5d96
feat(plugins): add registry search API and install dialog
agentofreality Mar 31, 2026
3ef6dce
feat: add hot-reload plugin tests and test-all Makefile target
agentofreality Apr 7, 2026
e71ee0e
fix: standardize plugin API error responses on ErrorResponse
agentofreality Apr 7, 2026
51699b3
refactor: replace default instance wrappers with middleware
agentofreality Apr 7, 2026
c3b1775
fix: validate path id matches body id in upsert handlers
agentofreality Apr 7, 2026
b506b19
fix: add path traversal protection to upgrade_plugin endpoint
agentofreality Apr 7, 2026
c18a764
perf: compile variable regexes once with LazyLock
agentofreality Apr 7, 2026
ae44d5f
fix: replace expect() with error handling in get_query handler
agentofreality Apr 7, 2026
ff19fb7
fix: preserve server-level settings across config persistence saves
agentofreality Apr 7, 2026
9643894
feat: add configurable CORS allowed origins
agentofreality Apr 7, 2026
8b06dc1
fix: add cors_allowed_origins to init_output_test fixtures
agentofreality Apr 7, 2026
b05c6ce
refactor: unify handler error types on ErrorResponse
agentofreality Apr 7, 2026
8ea393b
fix: add missing cors_allowed_origins field to basic_setup example
agentofreality Apr 8, 2026
efc6d93
fix: resolve cargo clippy --all-targets warnings
agentofreality Apr 8, 2026
a99c420
refactor: unify API error handling to use ErrorResponse consistently
agentofreality Apr 8, 2026
01e234a
refactor: remove dead code from init wizard and server
agentofreality Apr 8, 2026
2f95080
refactor: split large modules and fix test-all target
agentofreality Apr 8, 2026
7716b8a
fix: eliminate remaining error handling inconsistencies
agentofreality Apr 8, 2026
552d1de
fix: resolve clippy warnings for redundant closures and len_zero
agentofreality Apr 8, 2026
d567c2d
fix: replace sleep-based waits with wait_for_status in tests
agentofreality Apr 8, 2026
365fdac
fix: reuse HTTP client in push_source_data and fix plugin file path
agentofreality Apr 8, 2026
8230d92
fix: skip plugin-dependent tests and add OCI download target
agentofreality Apr 15, 2026
d362d3a
fix: correct duplicate step number in commit-staged skill
agentofreality Apr 17, 2026
25ea0b6
feat: support persist_index for dynamically created instances
agentofreality Apr 17, 2026
f689980
fix(examples): improve trading app robustness and cleanup
agentofreality Apr 17, 2026
0df7a1f
fix: parameterize API version prefix in HATEOAS links
agentofreality Apr 21, 2026
71cd3d7
fix: cancel hot-reload watcher on shutdown and use structural status …
agentofreality Apr 21, 2026
520a37d
fix: add read-only guards to plugin and solution mutation handlers
agentofreality Apr 22, 2026
b518bca
fix: correct misleading test log message in Makefile
agentofreality Apr 22, 2026
205d57d
feat: add plugin directory synchronization and fix trading demo startup
agentofreality Apr 22, 2026
8436026
fix: eliminate RwLock-across-await in all handler and startup paths
agentofreality Apr 22, 2026
2d03ef2
Remove partial plugin upgrade/migration/retire/promote scaffolding
agentofreality Apr 23, 2026
d5b440d
Mark C13 and C14 resolved in PR #84 review plan
agentofreality Apr 23, 2026
a5261c3
Address PR #84 review comments C3 and C9
agentofreality Apr 23, 2026
4ddc823
Remove PR #84 review plan tracking file
agentofreality Apr 23, 2026
2caa660
Upgrade drasi-* crates to latest published versions
agentofreality Apr 24, 2026
f9cf00f
examples(getting-started): add automated end-to-end runner script
agentofreality Apr 24, 2026
e2952e9
fix(api): surface persistence failures to API callers (PR #84 C2)
agentofreality Apr 24, 2026
48d154c
fix(config): surface schema-evaluation failures with stable codes (PR…
agentofreality Apr 24, 2026
e604bdc
fix(api): document and improve clone rollback observability (PR #84 C1)
agentofreality Apr 24, 2026
eb9dc00
docs(ui): make Web UI build step discoverable in source builds
agentofreality Apr 24, 2026
4a3278e
style(server): apply rustfmt to ui_dir warning block
agentofreality Apr 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/skills/commit-staged/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
name: commit-staged
description: Commit all staged files with an accurate, informative commit message. Use when asked to commit, make a commit, or save changes.
---

1. Run `git diff --cached` to review all staged changes.
2. Analyze the changes to understand what was modified and why.
3. Write a commit message following conventional commit style:
- A concise subject line (≤72 chars) summarizing the change
- A blank line followed by a body explaining what and why
- Include the Co-authored-by trailer
4. Let the user review the commit message and make edits if necessary before finalizing the commit. Never commit without user approval of the message.
5. Commit with `git commit -m "..."`.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,9 @@ logs/

# Vendored native libraries (downloaded from OCI registry)
vendor/

# UI build artifacts
ui/node_modules/
ui/dist/

.vscode
6 changes: 0 additions & 6 deletions .vscode/extensions.json

This file was deleted.

19 changes: 0 additions & 19 deletions .vscode/launch.json

This file was deleted.

12 changes: 0 additions & 12 deletions .vscode/mcp.json

This file was deleted.

5 changes: 0 additions & 5 deletions .vscode/settings.json

This file was deleted.

16 changes: 0 additions & 16 deletions .vscode/tasks.json

This file was deleted.

115 changes: 108 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,28 @@ This is the Drasi Server repository - a standalone server wrapper around DrasiLi
- Cross-compile: `make build-cross TARGET=x86_64-pc-windows-gnu`
- Run server: `cargo run` or `cargo run -- --config config/server.yaml`
- Run with custom port: `cargo run -- --port 8080`
- Run with plugin verification: `cargo run -- --verify-plugins --config config/server.yaml`
- Run with plugin verification disabled: `cargo run -- --skip-verification --config config/server.yaml`
- Run with UI disabled: `cargo run -- --disable-ui`
- Run with UI enabled (override config): `cargo run -- --enable-ui`
- Validate config (structure only): `cargo run -- validate --config config/server.yaml`
- Validate config (with plugins): `cargo run -- validate --config config/server.yaml --plugins-dir ./plugins`
- Check compilation: `cargo check`

### Plugin Loading
Plugins (sources, reactions, bootstrap providers) are loaded at runtime as cdylib shared libraries (`.so`/`.dylib`/`.dll`) from a `plugins/` directory next to the binary. Each plugin is self-contained with its own tokio runtime, communicating via a stable C ABI. Plugin building is managed by drasi-core, not this repository.

**Important: `[patch.crates-io]` does NOT affect plugins.** Cargo patches only affect compile-time dependency resolution for the server binary. Plugins are separate shared libraries loaded at runtime — they must be built separately. When developing with local drasi-core changes, always use `make build-local-plugins` to rebuild plugins from local source. Registry-downloaded plugins (`autoInstallPlugins: true`) will NOT be ABI-compatible with local drasi-core changes.

- Build all plugins from local drasi-core (release): `make build-local-plugins`
- Build all plugins from local drasi-core (debug): `make build-local-plugins-debug`
- Build test-only plugins (mock, log, scriptfile): `make build-local-test-plugins`
- Download test plugins from OCI registry (no drasi-core needed): `make download-test-plugins`

**Local directory plugin sources:** The `pluginRegistry` config field (and `--registry` CLI flag) accepts local filesystem paths in addition to OCI registry URLs. When a path is detected (e.g., `/path/to/plugins`, `./plugins`, `../drasi-core/target/debug/plugins`, `file:///opt/plugins`), the system scans the directory for plugin binaries instead of contacting an OCI registry. This is useful for development workflows where plugins are built locally. Detection is cross-platform: Unix absolute paths, relative paths (`./`, `../`), home-relative (`~/`), `file://` URIs, Windows drive letters, and UNC paths are all recognized as local directories.

### Testing
- Run all tests: `cargo test`
- Run all tests including plugin-dependent: `make test-all`
- Run unit tests only: `cargo test --lib`
- Run specific test: `cargo test test_name`
- Run integration tests: `./tests/run_working_tests.sh`
Expand All @@ -43,13 +57,17 @@ This repository contains only the server wrapper functionality:
1. **Server** (`src/server.rs`) - Main server implementation that wraps DrasiLib
2. **API** (`src/api/`) - REST API implementation with OpenAPI documentation
- `v1/` - API version 1 handlers, routes, and OpenAPI spec
- `v1/plugin_handlers.rs` - Plugin management API endpoints
- `shared/` - Common handlers, error types, and response types shared across versions
- `version.rs` - API version constants and utilities
- `models/` - Data Transfer Objects (DTOs)
- `mappings/` - DTO to domain model conversions
3. **Builder** (`src/builder.rs`) - Builder pattern for server construction
4. **Main** (`src/main.rs`) - CLI entry point for standalone server
5. **Dynamic Loading** (`src/dynamic_loading.rs`) - Runtime plugin loading from shared libraries
6. **Plugin Operations** (`src/plugin_operations.rs`) - Shared plugin management service used by CLI, init, startup, and API
7. **Plugin Orchestrator** (`src/plugin_orchestrator.rs`) - Server-level plugin lifecycle coordination (load, install, track)
8. **Plugin Registry** (`src/plugin_registry.rs`) - Re-exports from host-sdk: mutable registry with `Arc<RwLock<PluginRegistry>>`

### Core Components (External Dependency)

Expand Down Expand Up @@ -102,7 +120,12 @@ port: 8080
logLevel: "info"
persistConfig: true # Enable persistence (default)
persistIndex: false # Use RocksDB for persistent indexing (default: false, uses in-memory)
verifyPlugins: true # Enable cosign signature verification for downloaded plugins (default: false)
verifyPlugins: true # Enable cosign signature verification for downloaded plugins (default: true)
enableUi: true # Enable the web UI at /ui (default: true)

# Hot-reload plugin settings (default: all disabled)
# hotReloadPlugins: false # Enable filesystem watching for plugin changes
# hotReloadDebounceMs: 2000 # Debounce window in milliseconds

# Optional trusted identities for plugin signature verification
# trustedIdentities:
Expand All @@ -121,6 +144,12 @@ verifyPlugins: true # Enable cosign signature verification for downloaded plugi
# defaultDispatchBufferCapacity: 1000
# defaultDispatchBufferCapacity: "${DISPATCH_BUFFER_CAPACITY:-1000}"

# CORS allowed origins (default: empty = all origins permitted)
# When set, only listed origins are allowed for cross-origin requests.
# corsAllowedOrigins:
# - "http://localhost:3000"
# - "https://dashboard.example.com"

# Sources (parsed into plugin instances)
sources:
- kind: mock
Expand Down Expand Up @@ -182,6 +211,8 @@ The REST API is exposed under `/api/v1/instances/{instanceId}/...` for multi-ins

### Configuration Persistence

Persistence uses a snapshot-based approach: when saving, `ConfigPersistence::save()` calls `snapshot_configuration()` on each DrasiLib instance via the ComponentGraph. The ComponentGraph is the single source of truth — there are no shadow caches or separate registration steps. Mutations flow through the ComponentGraph, and the persisted YAML is reconstructed from the current graph state at save time.

DrasiServer separates two independent concepts:

1. **Persistence** - Whether API changes are saved to the config file
Expand All @@ -206,7 +237,7 @@ DrasiServer separates two independent concepts:
- This allows dynamic query creation without persistence (useful for programmatic usage)

**Behavior:**
- When persistence enabled: all API mutations (create/delete queries) are automatically saved to the config file using atomic writes (temp file + rename) to prevent corruption
- When persistence enabled: `save()` snapshots component state from the ComponentGraph and writes to YAML using atomic writes (temp file + rename) to prevent corruption
- When persistence disabled: API mutations work but changes are lost on restart
- When read-only: all create/delete operations via API are rejected

Expand Down Expand Up @@ -291,6 +322,8 @@ The server exposes a versioned REST API on port 8080 by default. All API endpoin
### Instance Management

- `GET /api/v1/instances` - List all DrasiLib instances
- `GET /api/v1/instances/{instanceId}/snapshot` - Get configuration snapshot of an instance
- `POST /api/v1/instances/{instanceId}/clone` - Clone components from another instance

### Component Management (Instance-Specific)

Expand Down Expand Up @@ -328,12 +361,74 @@ For convenience, the first configured instance is accessible via shortened route
- `GET/POST /api/v1/queries` - Queries of the first instance
- `GET/POST /api/v1/reactions` - Reactions of the first instance

### Plugin Management (Server-Wide)

Plugin endpoints are server-wide (not per-instance) since plugins are shared across all instances:
- `GET /api/v1/plugins` - List all loaded plugins with status
- `GET /api/v1/plugins/{pluginId}` - Get plugin details
- `POST /api/v1/plugins/load` - Load a plugin from disk
- `POST /api/v1/plugins/install` - Install from remote OCI registry
- `GET /api/v1/plugins/{pluginId}/dependents` - List dependent components
- `GET /api/v1/plugins/kinds` - List all available kinds (sources, reactions, bootstrappers)
- `GET /api/v1/plugins/kinds/{category}/{kind}/schema` - Get config schema for a kind

## Important Patterns

### Error Handling
- Use `anyhow::Result` for functions that can fail
- Custom `DrasiError` type for domain-specific errors
- Proper error propagation with `?` operator

Drasi Server uses a three-layer error pattern aligned with drasi-lib:

**Layer 1 — HTTP handlers → `ErrorResponse`:**
All API error responses use `ErrorResponse` from `src/api/shared/error.rs`, which implements
`IntoResponse` to automatically set the HTTP status code and serialize a structured
`{code, message, details?}` JSON body. Handlers return `Result<Json<ApiResponse<T>>, ErrorResponse>`.

```rust
// Good: handler returns ErrorResponse on failure
Err(ErrorResponse::new(error_codes::SOURCE_NOT_FOUND, "Source 'x' not found"))

// Good: convert DrasiError to ErrorResponse automatically
Err(ErrorResponse::from(drasi_error))

// Bad: DO NOT return bare StatusCode without body
Err(StatusCode::NOT_FOUND) // ← No error body!

// Bad: DO NOT return 200 OK with error in body
Ok(Json(ApiResponse::error("something failed"))) // ← Wrong status code!
```

**Layer 2 — Server services → `anyhow::Result`:**
Internal modules (server.rs, persistence.rs, factories.rs, plugin_orchestrator.rs, config/)
use `anyhow::Result` with `.context()` for rich error chains. These convert to `ErrorResponse`
at the handler boundary via `From<anyhow::Error>`.

**Layer 3 — drasi-lib → `DrasiError`:**
Calls to `DrasiLib` return `DrasiError` which converts to `ErrorResponse` via `From<DrasiError>`
with proper status code mapping (ComponentNotFound → 404, AlreadyExists → 409, etc.).

**Error codes** are defined in `src/api/shared/error.rs::error_codes` module. Use existing codes
or add new ones — never use ad-hoc string error codes.

**Rules for contributors:**
- Never return bare `Err(StatusCode::...)` from handlers — always use `ErrorResponse`
- Never return `Ok(Json(ApiResponse::error(...)))` — errors must have proper HTTP status codes
- Use `ErrorResponse::from(drasi_error)` to convert DrasiLib errors
- Use `anyhow::Result` with `.context()` in internal/service modules
- Add new error codes to `error_codes` module when needed
- **Never embed raw underlying error strings in `ErrorResponse.message`.** The
`message` field is a high-level human-readable description of the failure.
Underlying technical errors (`e.to_string()`, file paths, `DrasiError`
internals) belong in `ErrorDetail::technical_details`.

**Persistence failures:** Mutating handlers (create/delete source/query/
reaction, instance create, clone, etc.) call `persist_after_operation` which
returns `Result<(), ErrorResponse>`. If persistence fails after the in-memory
mutation has already succeeded, the helper returns `PERSISTENCE_FAILED` (HTTP
500) — handlers `?`-propagate this. The error message states explicitly that
the change was applied in memory but not persisted; the underlying
filesystem error (`e.to_string()`) is in `ErrorDetail::technical_details`.
Operators must retry the operation or restart after fixing the underlying
issue, since the runtime is now ahead of the on-disk YAML.

### Async/Await
- All I/O operations are async using Tokio
Expand All @@ -342,6 +437,8 @@ For convenience, the first configured instance is accessible via shortened route

### State Management
- Components track their status (Stopped/Starting/Running/Stopping/Failed)
- Plugins track their lifecycle (Loaded/Active/Failed)
- Plugin registry uses `Arc<RwLock<PluginRegistry>>` for concurrent read/write access
- Configuration persisted to YAML files (when persistence enabled)
- In-memory state for active components

Expand Down Expand Up @@ -429,4 +526,8 @@ server.run().await?;
- Plugin metadata validation checks SDK version (major.minor match) and target triple at load time
- All data processing logic resides in drasi-lib
- This repository focuses on API and server lifecycle management
- Plugin signature verification is available via `--verify-plugins` CLI flag or `verifyPlugins: true` in config. Uses Sigstore/cosign keyless verification against the Rekor transparency log.
- Plugin signature verification is enabled by default (`verifyPlugins: true` in config). Use `--skip-verification` CLI flag or `verifyPlugins: false` to disable. Uses Sigstore/cosign keyless verification against the Rekor transparency log.
- **Plugin lifecycle management**: Plugins can be loaded and installed at runtime via the `/api/v1/plugins/` API. Dynamic upgrade/replacement of a running plugin is not currently supported — restart the server to replace a plugin.
- **Plugin registry is mutable**: Uses `Arc<RwLock<PluginRegistry>>` — shared types (PluginRegistry, PluginLockfile, PluginLifecycleManager, PluginWatcher) live in `drasi-host-sdk`, re-exported by this repo
- **Component metadata**: Sources and reactions carry `pluginId` and `pluginVersion` in their ComponentGraph metadata
- **Shared plugin operations**: `PluginOperations` in `src/plugin_operations.rs` provides the single source of truth for plugin management used by CLI, init, startup, and API
Loading
Loading