Support matrix

This page lists what the weavster binary does today. It is re-checked at the end of every delivery phase. When the README or any other page disagrees with this page, this page is correct.

Every capability sits in exactly one tier:

Tier Meaning
Implemented (wired) Reachable from weavster server or the CLI and covered by an acceptance test that exercises the public API/CLI.
Library-only Code and unit tests exist in the source tree, but the running server does not use it. You cannot reach it from the API or CLI.
Enterprise-deferred An interface stub exists and returns a deterministic "not available" error. There is no MVP implementation.
Unsupported No working implementation exists, in the running binary or in the source tree.

Server and API

Start the server with weavster server 127.0.0.1:8080, or with a configuration file using weavster server --config weavster.yaml. By default every /api/v1 request must carry the header X-Weavster-CSRF: 1. listen.requireMarkerHeader: false removes that requirement.

Every /api/v1 route except login needs credentials. See Authentication.

Capability Tier Proof / notes
GET /api/openapi.yaml (no marker header needed) Implemented (wired) TestSupportMatrixWired/openapi, TestOpenAPIPublished, TestOpenAPIContract. The served document is exactly agent-docs/openapi.yaml; every route is documented and every documented operation is contract-tested.
Unversioned API paths (/api/flows = latest, today /api/v1/flows); Weavster-API-Version reply header Implemented (wired) TestUnversionedAPI. See REST API.
System information: GET /api/v1/system (per request, TLS as configured), /about, /password-requirements, /resources, /guid Implemented (wired) TestSupportMatrixWired/system, TestSystemInfo. See System information.
CSRF marker enforcement (400 without X-Weavster-CSRF: 1) Implemented (wired) TestSupportMatrixWired/csrf-marker
TRACE/TRACK rejected with 405 Implemented (wired) TestSupportMatrixWired/trace-blocked
Strict-Transport-Security, X-Frame-Options: DENY, Content-Security-Policy: frame-ancestors 'none', X-Content-Type-Options: nosniff headers Implemented (wired) TestSupportMatrixWired/security-headers. HSTS is sent even over plain HTTP.
GET/POST /api/v1/flows, GET/PUT/DELETE /api/v1/flows/{id} Implemented (wired) TestSupportMatrixWired/flows-*, TestFlowUpdateAndEnable. Flows are saved in the configured store (see Durable flow definitions below). A new server starts with no flows. A flow processes messages once it is started (see Flow lifecycle below). A flow id must be 1–128 characters from A-Z a-z 0-9 . _ - and not a reserved route word (export, import, redeploy-all, connector-names, ports-in-use, stats, or <action>-all); anything else returns 400. POST with an existing id returns 409. GET/DELETE of an unknown ID returns 404.
GET /api/v1/topology, GET /api/v1/topology/flows/{flowId} Implemented (wired) TestTopologyGraphs, TestSupportMatrixWired/topology-*, TestSchemaValidates. Built from the stored flows: the drill-down shows the source, transform, and destinations with message-path and route edges; flowId is flow:<id> (the path takes either form). Status is the lifecycle state, stopped for a stopped destination, and errored when at least half of the last 5 minutes' deliveries failed. JSON Schema in agent-docs/schemas/topology.schema.json. See Topology.
GET /api/v1/messages search (flowId, status, from/to, idFrom/idTo, contentType, minAttempts/maxAttempts, metadata.KEY, limit/offset, allow-listed sort; X-Total-Count), GET /api/v1/messages/{id}, /content, DELETE, POST …/reprocess Implemented (wired) TestSupportMatrixWired/messages, TestPipelineEndToEnd, TestMessagesAPI, TestMessageSearch, TestSearchFilterParity (memory, SQLite, PostgreSQL). Filters run in the store before paging; the same filters apply to export and bulk removal. Content needs messages:content; search, read, and content are audited. Export/import (GET /api/v1/messages/export, POST /api/v1/messages/import, gzip, optional AES-256-GCM, TestMessageArchive; CLI exportmessages/importmessages). See Processing messages.
Authentication (Basic or Bearer token) on every /api/v1 route except login Implemented (wired) TestAuthRequired
Per-route permissions (flows:view, flows:edit, messages:view, admin) Implemented (wired) TestPermissionMatrix
POST /api/v1/auth/login, /auth/logout, GET /auth/me, POST /auth/password Implemented (wired) TestLoginLogout, TestBootstrapGeneratedPassword. Tokens are in memory and expire after 12 hours.
First-run admin account (env var, secret file, or one-time generated password with forced change) Implemented (wired) TestBootstrapGeneratedPassword, TestBootstrapPasswordSources
Password policy and lockout (auth.* config) Implemented (wired) TestBootstrapPasswordSources
Durable local users (password changes and lockout state included) Implemented (wired) TestUsersSurviveRestart. Durable with store.dialect: postgres; the first-run admin is created once per database.
Secrets from environment variables or files (secrets.dir, default /run/secrets) for dsnEnv, passwordEnv, and the store's store.dsnEnv Implemented (wired) TestSecretsFromFiles, TestSecretReader, TestEnvSecretNames. See Server configuration.
User administration (/api/v1/users, CLI user list/add/remove/changepw) Implemented (wired) TestUserAdministration, TestPermissionMatrix. Permission users:admin. See Authentication.
User preferences (GET/PUT /api/v1/users/{name}/preferences), sign-in status (GET /api/v1/users/{name}/loggedin), password check (POST /api/v1/auth/password/check) Implemented (wired) TestUserExtras. Preferences are stored with the user. See Authentication.
Config map, global scripts, settings (/api/v1/configmap, /scripts, /settings; CLI importmap, exportmap, importscripts, exportscripts) Implemented (wired) TestConfigItems. Stored and managed only: flows do not use the config map and scripts are not run yet. See Config map, scripts, and settings.
Code snippets and snippet libraries (/api/v1/snippets, /api/v1/snippet-libraries; CLI snippet [library] with list, import, export, remove) Implemented (wired) TestSnippets. Stored and managed only: flows do not run snippets yet. See Code snippets and libraries.
Message pruning by age and count (prune.maxAgeHours, prune.maxMessages, prune.intervalMinutes; GET /api/v1/system/prune, POST …/start, POST …/stop; messages.pruned event) Implemented (wired) TestPruneMessages, TestPrune, TestPruneControl, TestPruneLoop, TestPruneHandlers. Only finished messages are pruned; busy ones are skipped. See Prune old messages.
Bulk message removal (DELETE /api/v1/messages by the search filters, all=true, restart=true); CLI clearallmessages, dump stats, dump events Implemented (wired) TestBulkMessageRemoval. Messages being processed are kept and counted as busy. See Processing messages.
Message trends (GET /api/v1/messages/trends: hourly or daily counts by status, optional flow) Implemented (wired) TestMessageTrends (PostgreSQL and memory). Counted from stored messages. See Processing messages.
XML responses by content negotiation (Accept: application/xml); request bodies JSON only Implemented (wired) TestXMLResponses, TestJSONToXML. See JSON and XML.
Statistics over time (GET /api/v1/stats/series: sampled lifetime statistics per flow; server config stats.sampleIntervalMs, stats.retentionHours) Implemented (wired) TestStatsSeries, TestStatsSurviveRestart, TestStats (every store backend). Samples and current/lifetime statistics are stored with every sample, after a reset and at stop, and loaded again at start, so they survive a restart with PostgreSQL. See Processing messages.
Getting started to a processed message (docs/getting-started.md, examples/getting-started/) Implemented (wired) TestGettingStartedDoc; CI compose job runs scripts/getting-started.sh against Docker Compose. See Getting started.
CI/CD samples: GitHub Actions and GitLab CI, plan on pull/merge request and apply on merge to main (docs/examples/ci/) Implemented (samples) TestCISamples runs each sample's weavster commands against a server and checks the page shows the files. Install is go install until release binaries exist. See CI/CD.
Alert definitions (/api/v1/alerts: create, get, update, delete, enable/disable, import with force, options, statuses, info, test as a dry run); CLI importalert, exportalert Implemented (wired) TestAlerts, TestAlertInfo. Definitions are stored and validated only: alerts do not fire yet, and a test sends nothing. See Alerts.
Dynamic lookups (/api/v1/lookups: groups, prefix matching, get, exists, batch, put, delete, import with replace) Implemented (wired) TestLookups (permissions; durability on PostgreSQL). Stored and served only: flows do not read lookups yet. See Dynamic lookups.
Full configuration export/import (GET /api/v1/config/export, POST /api/v1/config/import with force, nodeploy, overwriteConfigMap); CLI exportcfg, importcfg Implemented (wired) TestConfigTransfer. Users are not included. See Export and import the whole configuration.
Config-as-code document: typed sections for flows, alerts, snippets, libraries, scripts, config map, settings; strict validation; JSON Schemas per artifact kind; POST /api/v1/config/validate, CLI config validate and weavster config validate FILE... (offline: no server, no database) Implemented (wired) TestConfigValidate, TestConfigValidateOffline, TestSchemasPublished. See Config-as-code documents.
Config-as-code plan and diff against the live server (POST /api/v1/config/plan; CLI config diff, config plan) Implemented (wired) TestConfigPlan, TestLivePlan. Side-effect free; sections left out of the document are not managed. See Config-as-code documents.
Config-as-code apply (POST /api/v1/config/apply with the plan fingerprint, dryRun, reason; CLI config apply) Implemented (wired) TestConfigApply, TestConfigApplyHandler. Stale plans refused; a failing change rolls back every applied change; each attempt audited with its result. See Apply.
Events: search by type, flow, time, and afterId; get one, count, max id, export (/api/v1/events…) Implemented (wired) TestEventsAPI, TestEventHandlers, TestEventsSurviveRestart, TestEventWriter, TestEvents (every store backend). The API answers from the newest 10,000; every event is stored in the background and the newest are reloaded at start, so they survive a restart with PostgreSQL. prune.eventMaxAgeDays removes old stored events. See Processing messages.
Exit codes (shell, server, test) and Error: format; deprecated channel/codetemplate command names Implemented (wired) TestExitCodesAndDeprecatedCommands, TestServerConfigErrors. See Exit codes and errors.
Audit of API calls (mutations, message reads, logins, failed credentials) with case-insensitive redaction; PHI reads record what they disclosed (message count and ids, content part); entries stored and searchable (GET /api/v1/audit, audit:view) Implemented (wired) TestAuditLog, TestAuditDisclosed, TestAuditLogStored (stored, filtered, paged, audited when read, kept across a restart on PostgreSQL), TestAudit (every store backend). Written to stderr and the store; kept until prune.auditMaxAgeDays (default 0: kept forever) removes them. See Audit log.
HTTPS listener (listen.tlsAddress, tls.certFile/keyFile/minVersion), separate from the cleartext one; listen.contextPath Implemented (wired) TestServerConfigTLS, TestCLIOverHTTPS (HTTPS only under /weavster; outside it 404)
mTLS Unsupported
Message store selection: memory (default), postgres, disabled Implemented (wired) TestServerConfigStore, TestServerConfigErrors/sqlite-removed. PostgreSQL migrates its tables on the first start (TestServerOnPostgres). sqlite was removed as a server store (D-55); tests that restart the server run in the postgres CI job. disabled makes message search return 503 and message intake unavailable.
PostgreSQL message store (store.dialect: postgres): messages, flows, users, config items, lookups, search, trends Implemented (wired) TestServerOnPostgres (server with a restart), the store suite on PostgreSQL (TestStoreCRUDAndSearch, TestFlowStore, TestUsers…, TestConfigItems, TestLookups, TestSearchFilterParity, …), TestRebind, TestDialectDetection; run by the postgres CI job against PostgreSQL 16.
Schema migrations at startup: ordered, one transaction each, locked on PostgreSQL, the applying release recorded; a newer release's database refused (exit 1, not retried); upgrades from every earlier version keep the data Implemented (wired) TestUpgradeFromEveryVersion (SQLite and PostgreSQL), TestMigrateOrderEnforced, TestMigrateNewerSchemaRefused, TestMigrateFollowsSearchPath, TestRefusesNewerSchema, TestMigratesBeforeTraffic, TestPostgresConcurrentMigrate, TestOpenClosesHandleOnMigrationFailure. See Upgrades.
Store connection retries (store.maxRetry, store.retryWaitMs) Implemented (wired) TestServerConfigErrors/retry-exhausted, TestServerStopDuringStoreRetry. PostgreSQL only.
Durable flow definitions Implemented (wired) TestFlowsSurviveRestart. Durable with store.dialect: postgres. With memory or disabled, flows are lost on restart.
Server configuration file (weavster server --config FILE) Implemented (wired) TestServerConfigListen, TestServerConfigErrors. Strict YAML: unknown keys and invalid values exit 1. See Server configuration.
Refuse to run as root (override: WEAVSTER_ALLOW_ROOT=1) Implemented (wired) TestSupportMatrixPrivilegedGuard
GET /metrics (Prometheus): per-flow and per-connector message counters, flows by status, processing slots in use and refusals, Go runtime and process metrics Implemented (wired) TestOperationalMetrics (the real binary: metrics, stats, and events agree after real traffic), TestMetricsRoute, TestServerMetrics. Needs flows:view, no CSRF marker. See Metrics.
OpenTelemetry tracing Library-only Not initialized by the server (deferred, D-55).
Read-only web UI (/ui/): all flows and one flow's source, transform, and destinations, with status and counts, refreshed every 5 seconds; sign-in and sign-out only Implemented (wired) TestWebUI (also under listen.contextPath), TestRenderStates, TestLayout, TestReadOnly, TestPageHasNoInlineCode, TestUIMount. See Web UI.

Message processing

Capability Tier Notes
Per-destination start/stop (POST /api/v1/flows/{id}/destinations/{name}/{start,stop}) Implemented (wired) TestDestinationStartStop. Sources are not separate connectors yet.
Per-destination transforms and filters (destination transform) Implemented (wired) TestDestinationTransforms. Same DSL steps as the flow transform, applied to the flow output per destination. See Processing messages.
Response transform and response selector (responseTransform, responseSelector) Implemented (wired) TestResponseSelector. The selected destination's reply to the first delivery attempt is returned by POST /api/v1/flows/{id}/messages; only http destinations reply. See Processing messages.
Bulk update (PUT /api/v1/flows), connector names (GET /api/v1/flows/connector-names), ports in use (GET /api/v1/flows/ports-in-use), initialState for startup auto-deploy Implemented (wired) TestFlowOperations. API only. Ports in use lists the server's API listeners; flows do not listen on ports yet. See Processing messages and Flow lifecycle.
Flow definitions validated against the published agent-docs/schemas/flow.schema.json (create, update, import; unknown fields rejected) Implemented (wired) TestFlowSchemaEnforced, TestFlowSchemaPublished
Flow dependencies (dependsOn, validated, delete-protected), export (GET /api/v1/flows/export), import (POST /api/v1/flows/import, overwrite) Implemented (wired) TestFlowExportImport, TestDeployDependenciesAndDeleteRunning. Deploy also deploys undeployed dependencies; deleting a running flow undeploys it first. See Flow dependencies, export, and import.
Flow update/rename (PUT /api/v1/flows/{id}), enable/disable, auto-deploy of enabled flows at startup (flows.deployOnStartup) Implemented (wired) TestFlowUpdateAndEnable, TestDeployOnStartupDisabled
Flow lifecycle: deploy, undeploy, start, stop, pause, halt, resume, redeploy-all, with transitions enforced Implemented (wired) TestFlowLifecycle. API only. Deploy also deploys undeployed dependencies. See Flow lifecycle.
All-flows actions (POST /api/v1/flows/{deploy,undeploy,start,stop,pause,halt,resume}-all), statistics for all flows (GET /api/v1/flows/stats), statistics reset (POST /api/v1/flows/stats/reset, POST /api/v1/flows/{id}/stats/reset, lifetime) Implemented (wired) TestAllFlowsLifecycleAndStats, TestFlowCLI. CLI: resetstats [lifetime], flow reset-stats. See Flow lifecycle.
Message intake: POST /api/v1/flows/{id}/messages Implemented (wired) TestPipelineEndToEnd. See Processing messages.
Receive → persist → filter → transform → deliver to each destination, with per-destination results and aggregate status Implemented (wired) TestPipelineEndToEnd. Synchronous, one attempt; response processing through responseSelector/responseTransform (below).
http and file destinations Implemented (wired) TestPipelineEndToEnd, TestHTTPDestinationOptions. http takes method (POST/PUT/PATCH), timeoutMs, and maxRedirects (default 0; only 307/308, never https to http).
mllp destination: sends HL7 v2 over TCP (address, timeoutMs; tls with an optional caFile; frameStart/frameEnd/ackMode) and succeeds only on an AA/CA ACK for the message's control id (with ackMode: none, once the message is written) Implemented (wired) TestMLLPDestination, TestMLLPSinkACK, TestMLLPTLS, TestMLLPSinkTLS, TestMLLPClientTLS, TestMLLPModes, TestMLLPSinkMode. Needs an HL7 v2 message: HL7 passthrough (inputFormat: hl7v2, no transforms) or a build step with format: hl7v2; a connection per delivery; with tls the receiver's certificate and host name are always verified. See Send HL7 v2 over MLLP.
File source: a flow polls a directory (source: {type: file, dir, pattern, pollIntervalMs, moveTo, recursive}); files deleted or moved after the message is stored; rejected files moved aside or skipped Implemented (wired) TestFileSource, TestFileSourceRecursive, TestListFilesRecursive, TestCheckSource. At-least-once; only while the flow is started; regular files in dir (and, with recursive, its subdirectories up to 32 levels), never through symbolic links. See Read files from a directory.
HTTP source: a flow listens on its own address (source: {type: http, address, path, method}) while it is started Implemented (wired) TestHTTPSource, TestHTTPSourceSecured, TestSourceHandler, TestSourceHandlerBasicAuth, TestCheckSource. Optional HTTP Basic (username, passwordEnv), HTTPS (certFile, keyFile), and readTimeoutMs (TestHTTPSourceReadTimeout); one flow source per port; listed by GET /api/v1/flows/ports-in-use. See Receive messages over HTTP.
destinationSet step: the flow transform excludes destinations per message (exclude, optional when; exclusion only, D-20); stored with the message as destinationSet.excluded Implemented (wired) TestDestinationSet, TestProcessDestinationSet, TestCheckTransforms, TestValidateRefuses. See Route by content.
Processing order: flow transform steps in order → each destination's steps on the flow output → delivery → response transform Implemented (wired) TestProcessingOrder, TestDestinationTransforms. See Processing order.
Golden transform tests: every supported input (JSON, HL7 v2, XML, delimited) and output (JSON, HL7 v2, XML, text) run through the real server to an HTTP destination; body and Content-Type compared Implemented (wired) TestTransformGolden, TestGoldenFixtures (examples/golden/: the same cases run through the server and offline by weavster test; CI job golden keeps the JUnit results).
XML conversion without XSLT: XML view + steps + build xml Implemented (wired) TestTransformGolden/xml-to-xml, TestTransformGolden/xml-to-xml-filtered. No XPath functions, sorting, or loops. See Convert XML.
build step: the last step of a flow or destination transform renders the output from a template as JSON, HL7 v2, XML, or text, with values escaped for the format and the result checked Implemented (wired) TestBuildOutput, TestProcessBuild, TestBuild. See Build the output.
Transform schema: agent-docs/schemas/transform.schema.json describes exactly the steps that run (map, set, filter, destinationSet, build); flow, destination, and response transforms are checked against it by the API and config validate Implemented (wired) TestTransformSchema, TestValidateRefuses, TestSchemaPublishedAndMatchesTypes. destinationSet.include is refused (D-20).
Delimited input: inputFormat: delimited (delimited: {delimiter, header}) gives transforms {"rows": [...]} (objects by column name, or lists) with RFC 4180 quoting Implemented (wired) TestDelimitedInput, TestProcessDelimitedInput, TestDelimitedJSON, TestCheckInput. One message per file; at most 100,000 rows; output is JSON unless a build step produces another format. See Transform delimited text.
XML input: inputFormat: xml gives transforms the document as JSON (order.@id, order.patient.name.#text, repeated names as lists, #ns); DTDs never processed and declared entities never expanded (predefined ones such as &amp; are decoded) Implemented (wired) TestXMLInput, TestProcessXMLInput, TestXMLJSON. Output is JSON unless a build step produces XML; order between different child names and mixed-content position not kept; at most 256 levels and 100,000 elements. See Transform XML documents.
HL7 v2 input: inputFormat: hl7v2 gives transforms the message as JSON (PID.5.1, repetitions, subcomponents, escapes decoded, the message's own delimiters, every segment in order); versions 2.1–2.9 Implemented (wired) TestHL7Input, TestHL7Codec, TestProcessHL7Input, TestHL7JSON, TestHL7JSONSubcomponents, TestHL7JSONVersions, TestHL7RoundTrip, TestHL7ACKCustomDelimiters. Output is JSON unless a build step produces HL7 v2 again. See Transform HL7 v2 messages.
MLLP source: a flow accepts HL7 v2 over TCP (source: {type: mllp, address}, over TLS with certFile and keyFile; other framing with frameStart/frameEnd; no replies with ackMode: none) while it is started and answers each message with an HL7 ACK (AA stored, AR refused, AE not stored) Implemented (wired) TestMLLPSource, TestMLLPHandler, TestMLLPServer, TestHL7ACKOptions, TestMLLPTLS, TestMLLPModes, TestMLLPFraming, TestMLLPServerNoReply. No sender authentication (no mutual TLS); set inputFormat: hl7v2 to transform the messages. See Receive HL7 v2 over MLLP.
flow destination: hands a message to another flow in-process (flow: <id>), with source.flow/source.message metadata; targets follow the dependsOn rules Implemented (wired) TestFlowDestination, TestFlowSink, TestDependencies. Effectively once (a retry finds the stored message); what it sends must fit the target's inputFormat. See Send to another flow.
database destination: inserts each message's JSON values into a table of PostgreSQL or SQLite (driver, dsnEnv, table, columns, keyColumn), with parameters, quoted identifiers, one statement (its own transaction) per message within timeoutMs, and no duplicate on retry with keyColumn Implemented (wired) TestDatabaseDestination (SQLite file), TestSQLSink, TestSQLSinkStatement (PostgreSQL SQL), TestSQLSinkErrors, TestSQLValue, TestDBPool. Run against PostgreSQL 16 by the postgres CI job (TestPostgresDatabaseAdapters). See Write rows to a database.
database source: runs a read-only SELECT every pollIntervalMs or on a cron schedule and turns each row into a JSON message (driver, dsnEnv, query, idColumn, update, maxRows, timeoutMs), then marks it with update; at-least-once Implemented (wired) TestDatabaseSource (SQLite file), TestDatabaseSourcePoll, TestQuerySQL, TestJSONValue. Interval or cron schedule. Run against PostgreSQL 16 by the postgres CI job (TestPostgresDatabaseAdapters). See Read rows from a database.
Other sources and destinations (SMTP, SOAP/REST web service, document) Library-only Only file, http, mllp, and database sources and http, file, mllp, flow, and database destinations are wired.
Per-flow and per-destination statistics (GET /api/v1/flows/{id}/stats) Implemented (wired) TestStatsEventsTopology. In memory; reset, dump, and time series are not available.
Event log with processing events (GET /api/v1/events) Implemented (wired) TestStatsEventsTopology. The newest 10,000, kept across restarts with PostgreSQL. Filters, get, count, max id, and export: see the Events row above.
Topology activity from real counters on flow, source, transform, and destination nodes and on message-path edges, zeros included Implemented (wired) TestTopologyGraphs, TestStatsEventsTopology. Kept across restarts with PostgreSQL.
YAML DSL map, set, filter steps Implemented (wired) TestPipelineEndToEnd. build and destinationSet are not supported.
WASM executor (wazero), module registry Library-only Not used by the server. The executor has no WASI host.
File and database sources poll on an interval (pollIntervalMs) or a cron schedule (5 fields or @hourly/@every, optional CRON_TZ=) Implemented (wired) TestSourceSchedules, TestPollClock. See Poll on a schedule.
Scheduler library (durable jobs, leases, SQL job queue) Library-only The server's polling sources and retries do not use its job queue. Its SQL runs on PostgreSQL 16, claims with FOR UPDATE SKIP LOCKED (a locked job is skipped, not waited for), and hands each job to exactly one claimer: TestPostgresJobLifecycle, TestPostgresClaimSkipLocked, TestPostgresConcurrentClaims (postgres CI job).
Graceful shutdown bounded by listen.shutdownTimeoutMs; unfinished work resumes on the next start Implemented (wired) TestGracefulShutdownRequeuesInFlightWork
Delivery retries with persisted backoff, dead-lettered status, restart recovery Implemented (wired) TestRetryRecoversQueuedMessage, TestQueuedWorkSurvivesRestart, TestDeadLetterAfterMaxAttempts. Dead letters can be listed, requeued, and removed (next row).
Capacity, limits, and retention documented; secure defaults and a production configuration (HTTPS only, TLS 1.3, PostgreSQL, strict login policy) Implemented (wired) TestProductionExample starts the server from docs/examples/production/weavster-server.yaml. See Capacity and limits and Production setup.
Bounded processing: at most processing.maxConcurrent messages at once across the API and sources; busy senders get 503 + Retry-After (API, http), AE (mllp), or a later poll (file, database) after processing.waitMs Implemented (wired) TestBackpressure, TestProcessLimit, TestBackendErrorStatus, TestFileSourceBusy, TestDatabaseSourcePoll. See processing.
Per-destination attempt records: count, last error, protocol-specific lastCode (http:503, mllp:AE, sqlstate:…, net:…, tls:certificate, flow:not-running), lastAttemptAt, nextAttemptAt Implemented (wired) TestAttemptCodes, TestErrorCode, TestDeliverRecordsCode. See Search stored messages.
Dead letters: list, show, requeue (one or all; delivered destinations not re-sent; attempt counts in the audit log and a message.requeued event), remove (POST /api/v1/messages/{id}/requeue, POST /api/v1/messages/requeue, DELETE /api/v1/messages/{id}?status=dead-lettered; CLI deadletter list, show, requeue, remove) Implemented (wired) TestDeadLetterRequeue. See Dead-lettered messages.
Alerts and SMTP/webhook notifiers Library-only
In-server Git integration (repository, commit/log/diff/restore, push/pull, drift, plan/apply from a revision) and scheduled drift remediation Enterprise (removed from the MVP, D-55) Git is automation around the CLI and config files: keep weavster.yaml in your own repository and plan/apply it from CI (see CI/CD). internal/gitstore remains a library that the binary does not use. Flows in a config document (flows.<id>) use the same definition as the flow API and are validated against flow.schema.json (TestConfigFlowIsAPIFlow).
Legacy import Unsupported internal/migrate reads a made-up <weavster-export> XML schema, not any real legacy export format.

CLI

Capability Tier Proof / notes
weavster server [--config FILE] [address] Implemented (wired) TestSupportMatrixCLI/server-subcommand, TestServerConfigListen
weavster with no subcommand Implemented (wired) TestSupportMatrixCLI/no-subcommand, TestShell. Opens the interactive remote shell (weavster> prompt); quit, exit, or end of input ends it. Start the server with weavster server.
weavster -h Implemented (wired) TestRunHelpAndVersion
weavster -v Implemented (wired) TestRunHelpAndVersion, TestShell/server_version. Prints the server's version (and the client's). Needs credentials (-u/-p or -c); exits 2 if the server cannot be reached or refuses them.
weavster -s script.txt batch mode Implemented (wired) TestSupportMatrixCLI/batch-*, TestFlowCLI. Commands: help, status, version, flow (list, get, create, update, update-all, rename, enable, disable, remove, export, import, lifecycle actions, redeploy-all, start/stop-destination, connectors, ports, stats; flows by id or name), deploy [timeout], import "path" [force], export <id or name or *> "path"; double-quoted arguments, user list/add/remove/changepw, quit/exit. Exits 2 if any line fails (unknown command, usage error, unreadable file, unreachable server, or an error reply). See Command-line client.
-a address Implemented (wired) TestSupportMatrixCLI/batch-*, TestShell. Include the scheme, for example http://127.0.0.1:8080 (default).
-u, -p Implemented (wired) TestCLICredentials, TestShell. Checked at startup; a failed login prints Could not log in to server. and continues. Sent as HTTP Basic credentials; a warning when that would be plain HTTP to another host (TestCLIConnectionWarnings).
-ca / ca:: CLI over HTTPS with a private or self-signed CA (TLS 1.2+), with hints for untrusted or invalid certificates Implemented (wired) TestCLIOverHTTPS, TestWithCA, TestCertificateHints, TestConnectionCA. See Connect over HTTPS.
-c connection-file Implemented (wired) TestShell, TestConnectionCA. YAML with address, user, password, ca (a relative ca is next to the file); -a/-u/-p/-ca override it; a missing or invalid file exits 2.
-d Implemented (wired) TestShell/debug_shows_causes. Adds each underlying cause to error output.
Interactive shell Implemented (wired) TestShell. Same commands as batch mode. See Command-line client.
weavster test [--filter NAME] [--format junit\|json] [--output DIR] [PATH...] Implemented (wired) TestFixtures, TestFixtureErrors, TestRun, TestCodecRoundTrips. Finds fixture files (*.test.yaml, *.test.yml, *.test.json) and the flows of the config-as-code documents under the paths, and runs every case offline through the same transform code as the server (input format, flow transform, destinationSet, destination transforms); plus five built-in codec round trips. See Test your flows.

Example:

cat > smoke.txt <<'EOF'
status
flow list
EOF
weavster -a http://127.0.0.1:8080 -u admin -p 'PASSWORD' -s smoke.txt

Expected output: the /api/v1/system JSON document, followed by one line per flow: id, status, and name, separated by tabs. See Command-line client for every command.

Build and packaging

Capability Tier Proof / notes
Static CGO_ENABLED=0 builds for linux/amd64, linux/arm64, darwin/arm64 Implemented (wired) CI cross-build job. Release archives of these builds come from the release workflow below (no release has been tagged yet).
Distroless non-root container image Implemented (wired) CI docker job. Build it yourself with docker build -t weavster .. No image is published.
Release archives for linux/amd64, linux/arm64, darwin/arm64 with SHA-256 checksums (scripts/release.sh, published by the release workflow on a v* tag); weavster version Implemented (wired) CI release job (builds, verifies the checksums and the stamped version, publishes nothing), TestVersionCommand. Not signed (D-55). See Install.
Container configuration and secrets: configuration mounted read-only, state in PostgreSQL, secrets from environment variables or /run/secrets Implemented (wired) TestSecretsFromFiles (secret files), CI docker job. See Run in a container.
Docker Compose for local development: the server with PostgreSQL 16 (docker-compose.yml, docker/weavster.yaml) Implemented (wired) TestDockerCompose, CI compose job (scripts/compose-smoke.sh: a flow survives a server restart). Development credentials only. See Local development with Docker Compose.
Signed releases, curl \| bash installer Unsupported
Terraform / Pulumi samples (iac/) Library-only The binary does not read any value the samples emit.

Enterprise-deferred stubs

Only these stubs exist in the source tree, and none of them can be selected from configuration. Each always fails with the same error:

Stub Error
Broker queue/topic source and sink not implemented in this edition
DICOM source and sink not implemented in this edition
DICOM codec not implemented in this edition: DICOM codec (requires a licensed library)
KMS/Vault key rotation not implemented in this edition: KMS/Vault key rotation

What you see when you try to use one:

  • A flow with a broker or dicom source or destination, or inputFormat: dicom, is refused with 400. The message names the field and the values this edition allows, for example flow does not match flow.schema.json: /destinations/0/type: value must be one of "http", "file", "mllp", "flow", "database"; for a source, it lists the first few source types and how many more there are. weavster config validate refuses the same flow offline when it is in a config-as-code document (under flows:).
  • Nothing in this edition rotates keys: secrets are read from environment variables or files (see secrets).

These Enterprise features are not in this edition, not even as a stub:

  • Single sign-on (OIDC/SAML) and multi-factor authentication are not available: sign-in uses the server's own accounts.
  • External authorization policies (OPA/Cedar) are not available: permissions are the built-in set.
  • SIEM or immutable audit forwarding is not available: the audit log is written to the store and stderr.
  • A Kubernetes operator, Redis/NATS queues, and object storage are not available.

Codecs

The codecs below are libraries (tier, versions, and notes describe them); you can exercise them with weavster test, which round-trips HL7 v2, JSON, XML, delimited text, and raw bytes. The server handles HL7 v2, XML, delimited text, JSON, and raw bytes with its own readers and writers, as the "Server use" column says: to read messages for transforms (inputFormat), to write build output, and to acknowledge messages an mllp source receives. Where they differ, the processing docs describe the server's behavior.

Codec Tier Server use Versions / segments Acknowledgment Notes
delimited Library-only reads it for transforms (inputFormat delimited): RFC 4180 quoting, one-character delimiter any (configurable delimiter) no tab/pipe/comma; optional header; RFC 4180 quoting; round trip exact for canonical input
hl7v2 Library-only reads it for transforms (inputFormat hl7v2), writes it (build format hl7v2), acknowledges MLLP messages 2.1–2.9 segment/field/repetition/component/subcomponent yes MSH/MSA ACK; round trip byte for byte, any delimiters
json Library-only reads and writes it for transforms (the default) RFC 8259 no stdlib encoding/json; numbers exact; round trip keeps the value (keys sorted)
xml Library-only reads it for transforms (inputFormat xml), writes it (build format xml) XML 1.0 (XXE-safe) no no DTD/external-entity resolution by construction; round trip keeps namespaces, attribute order, and mixed content order
x12 Library-only ISA/GS/ST envelope yes 997 functional acknowledgment
ncpdp Library-only Telecommunication (FS/GS/RS delimiters) no fixed-width amount formatting; response limited
raw Library-only passes messages through unchanged (flows without transforms) any binary no passthrough
dicom Enterprise-deferred no requires a licensed library; interface stub only (gap #12)

Delivery guarantees per adapter

A failed destination is retried until delivery.maxAttempts (then dead-lettered), so wired destinations are at-least-once: an attempt whose response was lost is sent again. The HTTP destination sends the same Idempotency-Key on every attempt, so a receiver that honors it sees each message once. Rows marked "library" describe adapters the server does not use yet. No destination is exactly-once (that is deferred from the MVP); HTTP gives the receiver a key to drop repeats with, and a flow destination uses its key itself so a retry never adds a second message to the target.

Adapter Source Sink Guarantee Sends idempotency key
File wired wired at-least-once (a retry rewrites the same file name; a source file is read again if the server stops between storing the message and removing the file) no
HTTP wired wired at-least-once; effectively once when the receiver honors Idempotency-Key yes: Idempotency-Key header, the same for every attempt
TCP/MLLP wired wired at-least-once: the source sends AA once the message is stored, and the destination repeats a delivery whose ACK was lost; either way the receiver may see a message twice. With ackMode: none a destination counts a written message as delivered and a source gives the sender no confirmation, so a message lost in transit is not noticed no (the protocol has no field for one)
Database wired wired at-least-once; with keyColumn, effectively once: the key is inserted with the row, and a retry after a lost success inserts nothing only with keyColumn: the key is inserted into that column
SMTP — library not wired no
Web service (SOAP/REST) — library not wired no
Document — library not wired no
In-process inter-flow (flow destination) — wired at-least-once, effectively once: the delivery succeeds once the target stored its message, and a retry finds that message by its key instead of storing it again yes: kept with the target's message as source.idempotencyKey
Broker, DICOM Enterprise-deferred Enterprise-deferred — —