Spectio — headless integration, API and data model¶
Status: draft v0.1 · 2026-10-25 · author: Thomas Weber (with Claude)
Companion docs: synthesis.md (architecture, §7bis and §7quinquies), ui-spec.md (screens), decisions/log.md (decisions log).
0. Decisions in brief¶
- Headless first. The server is an engine-agnostic launch-and-monitor service. The web UI, the CLI, the MCP server, the WES facade and embedded elements in other tools (LabID, portals) are all clients of the same public API. Nothing the UI does is private.
- Single-user is a configuration, not a different system. One schema and one API for every deployment. A single-user install is a multi-user install with one user, one group and one project created at first start, and an authentication mode that maps local requests to that user.
- Everything belongs to a project. Every tenant row has
project_idandcreated_by; every list endpoint is filtered by the projects the caller can see. Adding users and groups later needs no schema migration, only data. - Principals, not just users. People, service accounts (LIMS, CI), AI agents, runners and the system itself are all principals with tokens and roles. Every decision and change records which principal made it.
- Extension points are plugins. Engines, input resolvers (
labid://,s3://,drs://…), output sinks, check providers, notifiers and identity providers are Python entry points, so an institute adds an integration without forking Spectio.
1. Deployment modes¶
| Mode | What runs | Typical use |
|---|---|---|
| Personal | spectio serve on a laptop or a login node, bound to 127.0.0.1, auth mode single |
One researcher, no setup |
| Team server | server + Postgres (or SQLite on local disk) + runners on clusters, auth mode oidc |
A lab or core facility |
| Headless | same server with --no-ui; only API, WES, webhooks, MCP |
Driven entirely by a LIMS, portal or CI |
| Embedded | team or headless server + Spectio elements inside another web app | LabID or an institute portal shows launch forms, run cards and reviews |
Runners always connect outward to a server; they never need inbound ports.
2. Integration patterns¶
A. LIMS-driven run (LabID)¶
sequenceDiagram
participant L as LabID (service account)
participant S as Spectio server
participant R as Runner (EMBL SLURM)
L->>S: POST /api/v1/runs (workflow, params, samplesheet rows with labid:// inputs, external_refs, Idempotency-Key)
S->>R: launch command
R->>R: resolver plugin turns labid://dataset/456 into a path on EMBL storage
R-->>S: engine events (Tower protocol / Snakemake logger)
S-->>L: webhook spectio.run.state_changed, spectio.gate.opened
L->>S: GET /api/v1/gates/{id} (or the reviewer decides in the embedded review element)
S-->>L: webhook spectio.run.completed
S->>L: sink plugin publishes the Workflow Run RO-Crate and registers outputs as LabID datasets
B. Standard client through WES¶
A portal or another WES client calls POST /ga4gh/wes/v1/runs with workflow_type: NFL or SMK. Spectio maps it to a native run in the caller's default project. Gates, pause and resume are available as WES extensions (/ga4gh/wes/v1/runs/{id}/x-spectio/...) and through the native API.
C. Host UI with embedded elements¶
The host backend exchanges its service token for a short-lived embed token limited to one resource and a few actions, then renders <spectio-launch-form>, <spectio-run-card> or <spectio-review>. The elements talk to the Spectio API directly with that token and emit postMessage events (spectio:run-launched, spectio:gate-decided) to the host page.
D. Observed or adopted CLI runs¶
A run started in a terminal with Spectio enabled is attached to the user's default project, or the project given by SPECTIO_PROJECT. It is the same run object as a UI or API launch.
E. Event-driven automation¶
A robot or instrument subscribes to spectio.gate.opened for a gate type, does its work, and calls POST /api/v1/gates/{id}/signals with its service-account token. Policy decides whether that signal resolves the gate or only adds evidence.
3. Extension points (plugins)¶
Python entry points, one group per kind (spectio.engine, spectio.notifier, …), loaded on the server or the runner as indicated. Each plugin declares its capabilities, config schema (JSON Schema, rendered as a settings form) and required scopes. The full contract (discovery, settings, instances and scopes, context, versioning, conformance tests, frontend plugins) and the packaging for the Python bundle, Docker Compose and Kubernetes are in architecture-plugins-and-packaging.md, which also adds the launcher, AI provider, file store, broker, API and CLI extension kinds and the plugin_instances table.
| Kind | Runs on | Examples | Contract |
|---|---|---|---|
| Engine adapter | runner | nextflow, snakemake; later cwl (cwltool/Toil), wdl (Cromwell/miniwdl) | launch, stop at stage, resume, cancel, event source |
| Input resolver | runner | file://, s3://, drs://, labid://, omero://, ena:// |
URI → local path or staged copy, with checksum |
| Output sink | server or runner | RO-Crate to LabID, copy to S3, register in OMERO, Zenodo / WorkflowHub deposit | called on run.completed or on gate decisions |
| Check provider | server | MultiQC general stats, TSV/CSV column, JSON path, h5ad obs table, VCF stats | file → item × metric table for gate checks |
| Evidence viewer | UI | HTML report (sandboxed), OME-Zarr, IGV, PDF, table, embedding scatter | MIME type / file pattern → viewer |
| Notifier | server | email, Slack, Mattermost, Teams, Matrix | event → message |
| Identity provider | server | OIDC (EMBL SSO, LS Login), LDAP | login → principal |
| Secret backend | server, runner | local encrypted store, HashiCorp Vault | credentials for resolvers and sinks |
4. API design rules¶
- Base path
{root}/api/v1, whererootis empty for a standalone install and/spectiowhen co-hosted with depictio (/depictio/api/v1) behind one domain; JSON; resource-oriented; OpenAPI 3.1 published at/api/v1/openapi.json; generated Python and TypeScript SDKs. - IDs: prefixed ULIDs (
run_01JB…,gate_01JB…,prj_01JB…), sortable, safe in URLs, unique across the instance. - Tenancy: every object returns
project_id,created_byandcreated_at. Collections are top level (/runs,/workflows,/gates) and filtered by?project=; without it, the caller sees every project they can read. Create calls takeproject_id, defaulting to the caller's default project, so single-user clients never need to send it. - Ownership is data, not path: no
/users/{id}/runspaths, so moving a run between projects or adding users never changes URLs. - Lists: cursor pagination (
?cursor=,limit≤ 200,nextin the response), filters (?state=running&workflow=wf_…&external_ref=labid:sample/123), sort (?sort=-created_at), sparse fields (?fields=). - Writes:
Idempotency-Keyon every POST that creates or triggers something;ETag/If-Matchon gates, change sets and settings to prevent lost updates when two reviewers act at once. - Long operations (catalogue import, RO-Crate export, cleanup) return
202 Acceptedwith anOperationresource (/operations/{id}). - Errors: RFC 9457
application/problem+jsonwith a stabletypeURI and, for validation, a list of field errors. - Versioning: only additive changes within v1; breaking changes go to v2; deprecations announced with
DeprecationandSunsetheaders. - Limits: per-token rate limits with
RateLimit-*headers; request size limits; files go through artefact endpoints, never in JSON bodies.
5. Endpoint catalogue (v1)¶
| Area | Endpoints |
|---|---|
| Session & me | GET /me (principal, default project, scopes), GET /me/projects, POST /auth/device + POST /auth/token (CLI device flow, phase 2), POST /embed-tokens |
| Users & groups | GET/POST /users, GET/PATCH /users/{id}, GET/POST /groups, GET/POST/DELETE /groups/{id}/members |
| Projects | GET/POST /projects, GET/PATCH /projects/{id}, GET/PUT/DELETE /projects/{id}/grants |
| Service accounts & tokens | GET/POST /service-accounts, GET/POST /tokens, DELETE /tokens/{id} (personal and service tokens, scopes, expiry, optional project restriction) |
| Workflows | GET/POST /workflows, GET /workflows/{id}, GET /workflows/{id}/versions, GET /workflow-versions/{id}/schema (params JSON Schema), POST /workflows:import (git, nf-core, Snakemake catalog, RO-Crate), GET/PUT /workflows/{id}/manifest (spectio.yml overlay) |
| Environments & runners | GET/POST /environments, GET/PATCH /environments/{id}, GET/PUT /environments/{id}/grants, POST /runners:register (one-time token → runner credential), GET /runners, GET /runners/{id}, runner channel WS /runners/{id}/channel (commands, heartbeats, file streaming) |
| Runs | POST /runs, GET /runs, GET /runs/{id}, POST /runs/{id}:cancel, :pause (after current stage), :resume, POST /runs/{id}:relaunch (mode, from stage, param overrides), GET /runs/{id}/graph, GET /runs/{id}/params, GET /runs/{id}/samplesheets (versions), GET /runs/{id}/lineage, PATCH /runs/{id} (name, tags, external_refs, project move) |
| Tasks & logs | GET /runs/{id}/tasks, GET /tasks/{id}, GET /tasks/{id}/attempts, GET /tasks/{id}/logs/{stdout|stderr} (range requests), GET /runs/{id}/logs |
| Artefacts | GET /runs/{id}/artifacts, GET /artifacts/{id}, GET /artifacts/{id}/content (streamed through the runner or presigned URL), GET /artifacts/{id}/preview |
| Gates (reviews) | GET /gates (queue: ?assigned_to=me&state=open), GET /gates/{id}, GET /gates/{id}/checks, GET /gates/{id}/items (paged, filterable), GET/PUT /gates/{id}/change-set (draft edits: item decisions, samplesheet, params, editable files), POST /gates/{id}/proposals (AI or robot suggestion), POST /gates/{id}/signals (external systems), POST /gates/{id}/decisions (approve, apply, go back, stop — with If-Match), POST /gates:bulk-decide |
| Events | GET /events?run=…&after=seq , GET /events/stream (SSE, resumable with Last-Event-ID) |
| Webhooks | GET/POST /webhooks, GET/PATCH/DELETE /webhooks/{id}, GET /webhooks/{id}/deliveries, POST /deliveries/{id}:redeliver |
| Provenance | GET /runs/{id}/ro-crate (JSON-LD or zip, profile: workflow-run or provenance-run), POST /runs:import-crate (prefill a relaunch) |
| Search | GET /search?q= (runs, workflows, tasks, samples by external ref) |
| Admin | GET/PATCH /settings, GET /audit-log, GET /plugins, GET /health, GET /version; full admin surface (users, groups, tasks, logs, health, branding, plugins, backups and restores, migrations, maintenance) under /admin/*, see admin-and-operations.md §5 |
| Ingest (engines) | /trace/* (Nextflow Tower protocol, token = run-scoped), POST /ingest/events (Snakemake logger, companion plugins) |
| Facades | /ga4gh/wes/v1/* (WES 1.1 + x-spectio extensions), /mcp (MCP server) |
Example: launch from a LIMS¶
POST /api/v1/runs
Authorization: Bearer spk_svc_… # LabID service account
Idempotency-Key: labid-order-8812
Content-Type: application/json
{
"project_id": "prj_01JB…",
"workflow_version_id": "wfv_01JB…", # nf-core/rnaseq 3.27.0
"environment_id": "env_01JB…", # EMBL SLURM · htc
"profile": "singularity",
"params": { "aligner": "star_salmon", "outdir": "spectio://results" },
"samplesheet": {
"param": "input",
"rows": [
{ "sample": "S1", "fastq_1": "labid://dataset/456/R1", "fastq_2": "labid://dataset/456/R2",
"strandedness": "auto", "external_refs": ["labid:sample/123"] }
]
},
"gates": "from-manifest",
"external_refs": ["labid:order/8812", "labid:project/77"],
"notify": { "webhook_ids": ["whk_01JB…"] }
}
201 with the run, its id, state: queued and links. Retrying with the same Idempotency-Key returns the same run.
6. Identity, tenancy and permissions¶
Sign-in methods, sessions, tokens, magic links, share links and pipeline provisioning are specified in authentication-and-access.md. This section owns principals, tenancy and roles.
Model¶
- Principal: anything that can act.
kind ∈ {user, service, agent, runner, system}. Users are people; service accounts are integrations (LIMS, CI, robots); agents are AI agents (with model and version recorded on each action); runners are Spectio processes on compute environments;systemis Spectio itself. - Group: a lab, team or facility. Flat in v1, with an optional
parent_idfor later hierarchy. Memberships carry a role:member,adminorpi(principal investigator, as in depictio); groups synced from the identity provider are flaggedsso_managed. - Project: the unit of ownership and sharing. Owned by one group. Visibility
private(grants only),group(all members of the owning group) orinstance(everyone can read). - Grant:
(project, principal or group, role), role ∈viewer < launcher < reviewer < editor < owner.viewer,editorandownermean exactly what they mean in depictio;launcherandreviewerare Spectio-only steps between viewer and editor (§13). - Environment grant: which projects or groups may launch on an environment. Clusters and their credentials belong to groups, not to users.
Roles on a project¶
| Action | viewer | launcher | reviewer | editor | owner |
|---|---|---|---|---|---|
| See runs, logs, artefacts | ✓ | ✓ | ✓ | ✓ | ✓ |
| Launch, relaunch, cancel own runs | ✓ | ✓ | ✓ | ✓ | |
| Decide gates (when the gate policy names them) | ✓ | ✓ | ✓ | ||
| Cancel anyone's runs, edit workflow manifests | ✓ | ✓ | |||
| Manage grants, webhooks, service accounts, delete | ✓ |
Gate policies in spectio.yml name principals or groups (humans: [group:rnaseq-core], agents: propose); the decision endpoint checks both the role and the policy.
Tokens and scopes¶
Personal tokens, service-account tokens and agent tokens share one format (spk_<kind>_<random>, stored hashed), with scopes (runs:read, runs:launch, gates:decide, gates:propose, artifacts:read, admin), an expiry, and an optional project restriction. Runner credentials are separate: a one-time registration token becomes a rotating runner credential bound to one environment.
Single-user mode¶
auth.mode: single(the default forspectio serve). At first start Spectio creates: the instance, a user named after the OS account, a grouppersonal, a projectdefaultowned by that group, and owner rights for the user.- Requests from
127.0.0.1/ a Unix socket without a token are treated as that user. Any remote access (another machine, a runner, an integration) still needs a token, created in Profile › Tokens or withspectio token create. - The UI hides the project switcher and sharing controls while there is a single project and user; all API fields are still present.
Moving to multi-user (no migration)¶
spectio auth enable oidc --issuer … --client-id … (EMBL SSO; LS Login for external collaborators), then link the existing local user to their OIDC identity, invite users, create groups and grant projects. Optional later: LDAP, SCIM group sync, and a CLI device authorization flow for spectio login. SAML 2.0 is supported as well as OIDC, because depictio uses SAML (§13).
Enforcement¶
One policy function can(principal, action, resource) in the service layer, used by the REST API, WES, MCP and the UI's server-rendered data alike. List queries join on visible_projects(principal). With Postgres, row-level security on project_id can be added as defence in depth. Every write appends to the audit log.
7. Database schema¶
Portable across SQLite (WAL, local disk, ≥ 3.51.3) and Postgres: ULID text primary keys, UTC timestamps, JSON in TEXT (SQLite JSON1) / JSONB (Postgres) through the ORM type, CHECK constraints instead of enums, no SQLite-only features. Every tenant table has project_id, created_by (principal) and created_at; mutable ones add updated_at and deleted_at (soft delete).
erDiagram
principals ||--o| users : "kind=user"
principals ||--o| service_accounts : "kind=service|agent"
principals ||--o{ tokens : owns
principals ||--o{ identities : "OIDC/LDAP links"
groups ||--o{ group_members : has
principals ||--o{ group_members : in
groups ||--o{ projects : owns
projects ||--o{ project_grants : shares
groups ||--o{ environments : owns
environments ||--o{ environment_grants : "who may launch"
environments ||--o{ runners : served_by
projects ||--o{ workflows : catalog
workflows ||--o{ workflow_versions : versions
workflow_versions ||--o{ manifests : "spectio.yml / overlays"
projects ||--o{ runs : owns
workflow_versions ||--o{ runs : instance_of
environments ||--o{ runs : executes
runs ||--o{ run_inputs : "samplesheet + params versions"
runs ||--o{ tasks : has
tasks ||--o{ attempts : retries
attempts }o--o{ scheduler_jobs : "n:m (arrays, groups)"
runs ||--o{ artifacts : produces
runs ||--o{ events : "append-only log"
runs ||--o{ gates : pauses_at
gates ||--o{ check_results : evidence
gates ||--o{ gate_items : items
gates ||--o{ change_sets : drafts
change_sets ||--o{ change_items : edits
gates ||--o{ decisions : resolved_by
projects ||--o{ webhooks : subscriptions
webhooks ||--o{ deliveries : outbox
projects ||--o{ external_refs : "LabID/LIMS links"
principals ||--o{ audit_log : actions
| Table | Key columns (besides id, created_at, created_by) |
|---|---|
principals |
kind, display_name, disabled_at |
users |
principal_id, email, username, default_project_id, preferences (JSON) |
service_accounts |
principal_id, owning_group_id, purpose (lims, ci, robot, agent), model (agents) |
identities |
principal_id, provider, subject, unique (provider, subject) |
tokens |
principal_id, hash, scopes (JSON), project_id (nullable), expires_at, last_used_at |
groups, group_members |
name, parent_id · group_id, principal_id, role |
projects, project_grants |
owning_group_id, name, visibility · project_id, grantee (principal or group), role |
environments, environment_grants |
owning_group_id, kind (slurm, k8s, local…), config (JSON) · environment_id, project_id or group_id |
runners |
environment_id, principal_id, version, last_heartbeat_at, status |
workflows, workflow_versions, manifests |
project_id, source (git, nf-core, catalog, crate), engine · revision, commit, params_schema (JSON) · kind (repo, overlay), content |
runs |
project_id, workflow_version_id, environment_id, state, stage_index, origin (ui, api, wes, cli-observed, cli-adopted), parent_run_id, relaunch_mode, idempotency_key, external refs via table |
run_inputs |
run_id, version, kind (params, samplesheet), content (JSON), checksum |
tasks, attempts, scheduler_jobs, attempt_jobs |
run_id, process_or_rule, stage, tag · task_id, n, state, exit, resources (JSON) · environment_id, native_id, array_index |
artifacts |
run_id, task_id, uri, mime, size, checksum, role (output, report, evidence) |
events |
run_id, seq, event_id, type, payload (JSON); unique (run_id, event_id) |
gates |
run_id, stage, state, policy (JSON), opened_at, etag |
check_results |
gate_id, check_key, item_key (nullable), value, verdict |
gate_items |
gate_id, item_key, kind (sample, cell-set, well, region…), attributes (JSON), verdict |
change_sets, change_items |
gate_id, state (draft, applied, discarded), etag · change_set_id, target (item, samplesheet, param, file), before, after, author |
decisions |
gate_id, principal_id, actor_kind, model, action, justification, evidence (JSON), change_set_id, idempotency_key |
webhooks, deliveries |
project_id, url, secret_hash, event_types (JSON) · webhook_id, event_id, status, attempts, next_attempt_at |
external_refs |
project_id, object_type, object_id, ref (e.g. labid:sample/123); index on ref |
audit_log |
principal_id, action, object_type, object_id, diff (JSON), ip |
Indexes on (project_id, created_at) for every list, (run_id, seq) for events, (state, project_id) for runs and gates, and ref for external references.
8. Events and webhooks¶
CloudEvents 1.0 envelope (id, source, type, time, subject, data), plus spectioproject and spectiosequence extensions.
| Type | When |
|---|---|
spectio.run.created, .state_changed, .completed, .failed |
run lifecycle |
spectio.stage.started, .completed |
stage boundaries |
spectio.task.failed, .retried |
noteworthy task events (full task stream via SSE only) |
spectio.gate.opened, .proposal_added, .signal_received, .decided |
reviews |
spectio.artifact.published |
reports and outputs |
spectio.runner.offline, .online |
environment health |
Delivery: at least once, from an outbox table written in the same transaction as the change; ordered per run by spectiosequence; HMAC-SHA256 signature in Spectio-Signature with a timestamp; exponential retry for 24 h; redelivery from the API.
9. Embedded elements¶
- Distributed as a small web-components bundle (
@spectio/elements), also usable as iframes. - The host backend calls
POST /api/v1/embed-tokenswith its service token:{resource: "run_…", actions: ["read", "decide"], ttl: 900}→ short-lived token for the browser. - Allowed host origins per instance (
frame-ancestorsand CORS allow-list). Styling follows the design tokens, so elements look native in depictio or LabID.
10. Standards compatibility¶
| Standard | Use |
|---|---|
| GA4GH WES 1.1 | facade for launching and tracking; Spectio states map onto WES states (AWAITING_REVIEW and PAUSED → PAUSED with detail in extensions) |
| GA4GH TRS, DRS | phase 2: catalogue as TRS; artefacts as DRS objects |
| RO-Crate | import workflows from Workflow RO-Crates (nf-core, WorkflowHub); export runs as Workflow Run / Provenance Run Crates with gate provenance |
| Nextflow Tower protocol | ingest only (runs launched with -with-tower) |
| CloudEvents | webhook envelope |
| OIDC | authentication (phase 2) |
11. UI consequences¶
- Project switcher in the top bar, hidden while there is one project.
- Owner and project shown on runs, workflows and environments; a Share dialog on projects.
- Settings tabs: Users & groups, Projects, Service accounts, Tokens, Webhooks, Plugins.
- Launch form: project and environment pickers filtered by grants.
12. Open questions¶
- LabID's API surface and authentication (to confirm with the MODIS team).
- Whether groups need hierarchy in v1 (institute → unit → lab).
- Default visibility for new projects (
groupis proposed). - Where environment credentials live when a cluster is shared by several groups.
13. depictio compatibility¶
Spectio and depictio must feel like one platform: same accounts, groups, projects and roles, same look, and runs in Spectio becoming dashboards in depictio without manual configuration. They keep separate databases (depictio: MongoDB + S3/Delta; Spectio: SQLite/Postgres) and integrate only through identity, tokens and APIs. Findings come from a code audit of depictio (25/10/2026; file references in the working notes).
13.1 Identity¶
| Topic | depictio today | Spectio decision |
|---|---|---|
| Login | email + password, Google OAuth, SAML 2.0 (tested with Keycloak), magic links; no OIDC | support SAML 2.0 and OIDC; recommended deployment: one identity provider (or Keycloak as broker) for both apps, same group attribute (memberOf) |
| Co-deployed, before SSO | depictio issues RS256 JWTs | Spectio trusts depictio's JWTs (public key or GET /depictio/api/v1/auth/me), creates or updates the principal with an identity link depictio:user/<id>, same email: one login for both |
| Admin | User.is_admin bypasses permissions |
same flag and meaning |
| Single-user | anonymous admin anonymous@depict.io |
Spectio's local user maps to depictio's anonymous admin when both run single-user; no tokens on localhost |
| Service identity | provisioning API key, long-lived tokens of a service user | Spectio holds one depictio service credential (server side), used to provision or act as the run owner; runners get a scoped token, never depictio's S3 root secret |
| CLI | ~/.depictio/CLI.yaml, DEPICTIO_CLI_* |
~/.spectio/config.yaml, SPECTIO_*; spectio login can reuse a depictio token when the server trusts depictio |
13.2 Tenancy and roles¶
| Spectio | depictio | Rule |
|---|---|---|
Principal user |
User |
matched by email, linked by depictio:user/<id> |
Principal service / agent |
none | stays on the Spectio side |
Group (member / admin / pi, sso_managed) |
Group (users_ids, admin_ids, pi_id, sso_managed) |
same names and members; synced from the same identity provider |
| Project | Project |
linked 1:1 by external_refs (depictio:project/<id> ↔ spectio:project/<id>) |
Visibility instance / group / private |
is_public / group grants / direct grants |
instance ↔ is_public; group ↔ group_viewers of the owning group |
Roles viewer · editor · owner |
viewers · editors · owners |
identical meaning, highest role wins (direct or through a group) |
Roles launcher, reviewer |
— | Spectio-only; when mirrored to depictio they become viewer (they must not gain edit rights on dashboards) |
13.3 Run → dashboard hand-off¶
depictio already knows how to build a project from a pipeline's results (versioned templates for about 35 nf-core pipelines, depictio ingest --pipeline-id --triggered-by --attach-run --user --provenance-file --result-json). Spectio drives that path:
# spectio.yml (or the workflow's settings in Spectio)
depictio:
on: completed # or gate:<id> · stage:<n>
template: auto # by pipeline id, e.g. nf-core/rnaseq/3.27.0; or an explicit template id
project: linked # the depictio project linked to this Spectio project
attach_run: true # one depictio run per Spectio run (run_tag = Spectio run ID)
- On the trigger, the runner (which sits next to the results) runs
depictio-cli ingest <outdir> --pipeline-id <org>/<name>/<version> --triggered-by spectio --attach-run --user <owner email> --provenance-file <run summary or RO-Crate> --result-json <file>, with a short-lived credential from the server. - The server stores the returned project and dashboard links on the run, shows Open in depictio in Run detail and emits
spectio.run.dashboard_ready. - For runs Spectio launches, depictio's own Nextflow
onCompletetrigger is turned off (--depictio_enabled false) to avoid ingesting twice. For Snakemake, Spectio provides the trigger depictio lacks. - Later, a server-to-server ingestion call can replace the CLI when depictio reads the storage directly.
- Filter artifacts from gates (cell keep lists, bin lists, excluded samples) are passed to depictio as part of the provenance, so dashboards show the reviewed data.
13.4 Shared conventions¶
- Pipeline identifier:
<org>/<name>/<version>everywhere (depictio template IDs, Spectio workflow versions, RO-Crate, WESworkflow_urlresolution). - IDs: each side keeps its own (ObjectId, prefixed ULID) and links both ways through
external_refs. - Paths when co-hosted:
/depictio/…and/spectio/…on one domain, shared SSO session. - Events: depictio uses a WebSocket, Spectio SSE and webhooks; only
spectio.run.dashboard_readyis bridged (it refreshes the depictio project).
13.5 UI consistency¶
- One branding model: when co-deployed, Spectio reads depictio's instance
BrandTheme(primary, secondary, tertiary, surfaces, fonts, radius), so an institute brands both apps once. - Shared pages look the same as depictio's: Profile (email, name, title, role, ID, dates, avatar, tokens) and project sharing (Visibility · Members · Groups).
- Settings follow depictio's Administration grouping: People (Users, Groups, Service accounts) · Content (Projects, Workflows, Environments) · Activity (Runs, Events, Logs, Health) · Instance (Branding, AI & agents, Webhooks, Settings).
- Section colours: Projects and Administration/Settings use depictio's roles (secondary teal, primary blue) when co-deployed. Spectio's own menus keep their colours, except Workflows, which moves from orange to coral 700 (
#A54666) so it is not mistaken for depictio's Dashboards orange. - An app switcher in both top bars and deep links both ways: run → dashboard, dashboard → producing run and gate decisions.