Releases: oxur/textrynum
0.4.0 Release Notes
Released: 2026-03-21
Commits: 64 (since v0.3.0, 2026-03-12)
Diff: 213 files changed, 66,828 insertions, 1,242 deletions
Highlights
This release introduces the ECL Pipeline system — a complete Extract-Conform-Load
framework spanning specification, state management, topology resolution, a pipeline
runner, source adapters, sink stages, transform stages, a CLI, and secret management.
It also includes Fabryk-side bug fixes, documentation improvements, and dependency
updates.
New Crates (14)
ECL Pipeline Core
- ecl-pipeline-spec — Pipeline specification layer: source/stage/sink definitions,
credential references, data stream routing (milestone 1.1) - ecl-pipeline-state — Pipeline state types: item tracking, provenance, content
hashing with Blake3 (milestone 1.2) - ecl-pipeline-topo — Topology resolution: DAG construction from specs, stage
ordering, trait definitions for adapters/stages (milestone 1.3 + 2.3) - ecl-pipeline — Pipeline runner: execution engine, named data streams for
multi-stream routing, crash-safe persistence via RedbStateStore
(milestones 2.1, 2.2, 8.1)
Source Adapters
- ecl-adapter-fs — Local filesystem source adapter (milestone 3.1)
- ecl-adapter-gcs — Google Cloud Storage source adapter (milestone 7.3)
- ecl-adapter-gdrive — Google Drive source adapter with auth and content
download (milestones 4.1, 4.2) - ecl-adapter-sftp — SFTP source adapter with key/password auth
(milestone 9.2) - ecl-adapter-slack — Slack stub adapter for SourceAdapter validation
(milestone 6.1) - ecl-adapter-zapier — Zapier webhook push source adapter
(milestones 7.1, 7.2)
Sink Stages
- ecl-sink-gcs — GCS sink for error/rejected item output (milestone 7.6)
- ecl-sink-kafka — Kafka sink with Avro serialization and Schema Registry
integration (milestone 7.5)
Transform Stages
- ecl-stages — Built-in pipeline stages: CSV parsing, field mapping, validation,
aggregation, join, batch grouping, date parsing, timezone conversion, lookup,
decompression (ZIP/GZIP), and receipt assembly
(milestones 3.1, 7.1, 7.2, 7.4, 8.2-8.7)
Infrastructure
- ecl-secrets — Secret management foundation for credential resolution
(milestone 9.1)
ECL CLI
- ecl-cli — Pipeline CLI commands:
run,resume,status,inspect,
items,diff(milestone 5.1) - Observability and reporting: tracing spans, timing, Display impls
(milestone 5.2)
Fabryk Improvements
Bug Fixes
- Fix UTF-8 character boundary panic in
find_snippet()full-text search - Use
floor_char_boundaryto prevent panics in snippet truncation - Add serde backward compatibility for older graph JSON formats
- Re-export
ErrorCodeandAnnotateAblefromfabryk_mcp::model - Migrate
serde_yamlreferences toyaml_serde
Enhancements
- Add
with_names()/with_descriptions()to all MCP tool registries - Add shared config infrastructure to
fabryk-cli - Log service state transitions at appropriate severity levels
Documentation
- Comprehensive Fabryk MCP server howto guide
- MCP discoverability guide iterated for better agent-driven results
- ECL pipeline redesign research and crate analysis
- Rust workflow/pipeline ecosystem survey (2026)
- ECL pipeline runner design doc (0017 v1.1) — Rust quality pass
- Phase 1-6 milestone implementation plans
Integration Tests
- Giant Eagle end-to-end pipeline tests (Phase 2, milestone 8.8)
- Affinity end-to-end pipeline tests (Phase 1, milestone 7.8)
- File lifecycle management for GCS pipelines (milestone 7.7)
- Pipeline runner integration test suite (milestone 3.2)
Maintenance
- Dependency updates (batch bump)
- Collapse nested if-let statements into let-chains (clippy)
- Add missing package metadata across all crates
- CI fixes: protobuf-compiler for lance-encoding, libcurl-dev for rdkafka-sys
- Upgrade actions/checkout v4 to v6 for Node.js 24 support
0.3.0 Release Notes
Highlights
This release significantly expands the fabryk-mcp-core crate with three
major additions: a composable ServerGuidance builder that unifies server
instruction generation, a ResourceRegistry trait that enables MCP resource
support (list, read, subscribe, unsubscribe), and per-URI subscription
tracking in Notifier. The DiscoverableRegistry gains a from_guidance()
constructor that eliminates repetitive wiring between guidance and registry
setup. Downstream MCP servers can now compose custom HTTP routers without
adding direct dependencies on fabryk-core or axum, thanks to new
re-exports from fabryk-mcp-core. Workspace dependency versions were also
broadly updated across crates.
Features
fabryk-mcp-core: ServerGuidance builder (guidance.rs)
A new ServerGuidance struct provides a single composable builder for all
server instruction mechanisms. It replaces scattered with_description,
with_discoverable_instructions, and with_query_strategy calls with a
declarative structure that can be shared between FabrykMcpServer and
DiscoverableRegistry.
Key capabilities:
ServerGuidance::for_domain(domain)— creates guidance scoped to a named
domain.- Builder methods:
.context(),.workflow(),.convention(),
.constraint(),.subscribe(),.connector(),.data_freshness(),
.tool_meta(),.tool_metas(). to_instructions()— generates theServerInfo.instructionstext,
including a directory-first directive, context, subscription
recommendations, conventions, and constraints. Sections are omitted when
empty.directory_tool_name()— returns the canonical{domain}_directorytool
name.FabrykMcpServer::with_guidance(&guidance)— apply guidance to the server
in one call.
fabryk-mcp-core: ResourceRegistry trait (resource.rs)
A new ResourceRegistry trait abstracts over MCP resource listing and
reading, allowing domains to expose subscribable resources to MCP clients.
resources() -> Vec<Resource>— lists all available resources.read(uri) -> Option<ResourceFuture>— async read by URI; returnsNone
for unrecognized URIs.FabrykMcpServer::with_resources(registry)— registers a resource registry
and advertisesresources/list,resources/read,resources/subscribe,
andresources/unsubscribein server capabilities.
fabryk-mcp-core: Per-URI subscription tracking in Notifier (notifier.rs)
Notifier now maintains a per-URI subscription map in addition to the
broadcast peer list.
subscribe_resource(uri, peer)— registers a peer's interest in a specific
URI.unsubscribe_resource(uri)— removes all subscriptions for a URI.resource_updated(uri)— if any peers have subscribed to the URI, only
those peers are notified; otherwise all connected peers receive the
notification (backwards-compatible broadcast).resource_list_changed()— broadcasts a resource-list-changed notification
to all peers.- Dead peers are pruned automatically on each broadcast.
fabryk-mcp-core: DiscoverableRegistry.from_guidance() (discoverable.rs)
DiscoverableRegistry gains a from_guidance(registry, &guidance)
constructor that populates all fields (tool metadata, workflow/query strategy,
connectors, subscriptions, conventions, constraints) directly from a
ServerGuidance value, removing the need to pass each field individually.
The directory tool output now includes sections for recommended subscriptions,
conventions, and constraints alongside the existing tool catalog.
fabryk-mcp-core: Re-exports of ServiceHandle, ServiceState, and axum
Downstream MCP servers can now access service lifecycle types and HTTP
composition primitives without adding direct crate dependencies:
fabryk_mcp_core::ServiceHandleandfabryk_mcp_core::ServiceState
(re-exported fromfabryk-core).fabryk_mcp_core::axum(re-exported behind thehttpfeature flag),
enabling custom HTTP router composition.
Improvements
fabryk-mcp-core: Server resource handler integration (server.rs)
FabrykMcpServer integrates the new ResourceRegistry and subscription
infrastructure into the ServerHandler implementation. The server now
handles resources/list, resources/read, resources/subscribe, and
resources/unsubscribe protocol messages and wires subscription/
unsubscription events to the Notifier automatically.
Bug Fixes
Publish tooling: differentiated rate-limit delays for new vs existing crates
The publish Makefile target now queries the crates.io API before each
publish to determine whether a crate is new or already exists, then applies
the appropriate delay:
- Existing crates: 72 seconds (crates.io allows 1 publish per minute with
a burst of 30, plus index propagation buffer). - New crates: 624 seconds (crates.io allows 1 new crate per 10 minutes
with a burst of 5, plus initial indexing buffer).
Previously a single fixed delay of 372 seconds was applied to every publish,
which was both too slow for existing crates and too fast for first-time
publishes of new crates.
Infrastructure
Workspace dependency version bumps
Cargo.toml dependency versions were updated across the following crates:
ecl-cli, ecl-steps, ecl-workflows, fabryk-acl, fabryk-auth-google,
fabryk-cli, fabryk-content, fabryk-fts, fabryk-graph,
fabryk-mcp-content, fabryk-mcp-fts, fabryk-mcp-graph,
fabryk-mcp-semantic, fabryk-mcp, fabryk-vector, and fabryk. The
Cargo.lock file was updated to reflect resolved dependency changes.
Crates Updated
| Crate | Change |
|---|---|
fabryk-mcp-core |
Major feature additions (guidance, resources, subscriptions, re-exports) |
fabryk-mcp |
Dependency version bump |
fabryk-mcp-content |
Dependency version bump |
fabryk-mcp-fts |
Dependency version bump |
fabryk-mcp-graph |
Dependency version bump |
fabryk-mcp-semantic |
Dependency version bump |
fabryk |
Dependency version bump |
fabryk-acl |
Dependency version bump |
fabryk-auth-google |
Dependency version bump |
fabryk-cli |
Dependency version bump |
fabryk-content |
Dependency version bump |
fabryk-fts |
Dependency version bump |
fabryk-graph |
Dependency version bump |
fabryk-vector |
Dependency version bump |
ecl-cli |
Dependency version bump |
ecl-steps |
Dependency version bump |
ecl-workflows |
Dependency version bump |
v0.2.0 Release Notes
Highlights
-
Restructured crate hierarchy. Fabryk now ships two clean umbrella crates (
fabrykand
fabryk-mcp) that each re-export their constituent sub-crates. Downstream projects that
previously depended on five or more individual crates can now express that as one or two
[dependencies]lines. This is the most visible breaking change in this release. -
New crates. Three crates were added:
fabryk-gcpfor GCP credential detection,
fabryk-mcp-semanticfor deferred vector-backend wiring, andfabryk-redisfor Redis
integration and deployment utilities. -
Service lifecycle maturity. Services now support parallel startup with retry, a generic
health router, an audit trail, and a structured async startup pattern. These foundations
underpin the new how-to guides included in the release. -
Rust edition 2024, MSRV 1.85, and a trimmed dependency tree. Seven major dependencies
were upgraded, three were removed, and the workspace migrated tothiserror2 andtoml1.
Features
New Crates
-
fabryk-gcp— GCP credential detection crate. Provides helpers for locating and
validating Google Cloud credentials at runtime, along with thelog_error_chainutility
that is now shared across the workspace. (8e998e9) -
fabryk-mcp-semantic— AddsVectorSlot, a deferred-wiring abstraction that lets an
MCP server register a semantic-search backend without requiring the vector store to be
available at startup time. (0d92313,4e8cbd5) -
fabryk-redis— Redis integration crate including a deploy module and auth middleware
updates. (16cb42a)
MCP Infrastructure
-
HTTP transport —
fabryk-mcpnow supports Streamable HTTP transport behind an optional
httpfeature flag. (80094c7) -
DiscoverableRegistry— A new registry type that exposes rich metadata to AI agents
when they connect to an MCP server, making tool suites self-describing. (dbc1b4a,
932b7e4) -
MCP schema validation — Input schemas are now validated on registration; previously,
tools could be registered with an emptyinputSchema, which is now caught and rejected.
(6589bed) -
MCP diagnostics tools — Diagnostic tool handlers were added alongside the new
fabryk-mcp-semanticcrate. (4e8cbd5)
Service Lifecycle
-
Parallel startup with retry — Services can now be started concurrently and monitored
with configurable retry logic, reducing total startup time for multi-service deployments.
(d111e63) -
Generic health router —
health_routeris now generic over the application state type,
allowing it to be embedded in any Axum application without type-parameter conflicts.
(eba8ca7) -
Audit trail — Service lifecycle events are now recorded in a structured audit trail,
making it easier to diagnose startup and shutdown sequencing. (d111e63)
CLI
vectordb get-modelcommand —fabryk-cligains a new subcommand to query the
currently configured embedding model. Available when thevector-fastembedfeature is
enabled. (1945aa6)
Workspace Utilities (textrynum-util / textyl)
-
Workspace version management —
textylcan now read and write the workspace version,
query individual crate versions, and bump versions across the workspace in one operation.
(6da00bd) -
--project-version/--deps-versionflags —textylis no longer specific to the
Textrynum repository and can be used against any Rust workspace. (c55f63f) -
publish-orderand--excludeflags —textylnow prints the correct publish order
for workspace crates and supports excluding crates from that list. (139bb4c)
Improvements
Crate Hierarchy Refactor
The Fabryk workspace was restructured so that fabryk and fabryk-mcp act as umbrella
crates that re-export all sub-crates. The previous flat structure required consumers to
declare each sub-crate individually. The new layout reduces the integration surface to two
crates in the common case. (ccb078c)
Dependency Upgrades
Seven major-version dependency upgrades were applied across this release cycle:
| Dependency | From | To |
|---|---|---|
rmcp |
1.0 | 1.1 |
toml |
0.9 | 1.0 |
tantivy |
0.22 | 0.25 |
fastembed |
4 | 5 |
jsonwebtoken |
9 | 10 |
rkyv |
0.7 | 0.8 |
async-walkdir |
1 | 2 |
dirs |
5 | 6 |
Three previously declared dependencies were removed as unused. (561da8e, f142357)
Rust Edition and MSRV
The workspace migrated to Rust edition 2024 with a minimum supported Rust version of
1.85. thiserror was upgraded from 1 to 2 as part of this migration. (05d0e39)
Bug Fixes
-
Serialized env-var tests — Environment-variable-dependent tests in
fabryk-cliwere
failing non-deterministically when run in parallel. A mutex now serializes these tests.
(8dd9072,74032b0) -
Reduced
log_error_chainnoise —log_error_chainwas emitting redundant output
when called from high-frequency paths. Logging verbosity was reduced. (74032b0) -
MCP
concepts_getparameter documentation — Theidparameter forconcepts_getwas
described ambiguously. It is now clearly documented as a slug, obtained from the
concepts_listresults. (e4c6820) -
Internal path dependency versions — After the 0.1.0 release, internal path dependencies
retainedversion = "0.1.0"while the workspace had moved to0.1.1, causing publish
failures. All internal versions are now kept in sync viatextyl. (808e788) -
PUBLISH_ORDERin Makefile — The publish target listed crates in an order that did not
respect dependency edges, causingcargo publishto fail on the first attempt. The order
has been corrected. (bd4b458) -
Minor code quality issues — Three issues identified in a code audit were addressed:
an unused import, an unneeded clone, and a redundant type annotation. (ef30512)
Documentation
-
How-to guides — Four new how-to guides were added and are linked from the workspace
README:- Connecting Fabryk MCP servers to Claude Code over Streamable HTTP (
dc8e37a) - The MCP async startup pattern for deferring expensive service initialization (
ae4540a) - Adding a service-aware
/healthendpoint to an MCP server (eba8ca7) - Giving AI agents rich metadata via
DiscoverableRegistry(932b7e4)
- Connecting Fabryk MCP servers to Claude Code over Streamable HTTP (
-
How-to directory — How-to documents were moved from scattered locations into a
dedicateddocs/howtos/directory, with a corresponding README section. (23f750d) -
Crate-level READMEs and images — README files and associated images were relocated into
their respective crate directories to keep documentation co-located with code. (b2fe4a1) -
Architecture diagram — The workspace architecture diagram was updated to reflect the
v0.2.0 crate restructure, along with an AI prompt for maintaining the diagram in future
releases. (0850343,04d1f2c)
Infrastructure
- CI: protobuf installation — The
arduino/setup-protocGitHub Action was replaced with
a directaptinstall. The Action was hitting GitHub API rate limits in CI runs and
producing intermittent failures. (7447adb)
Upgrading from 0.1.x
The primary breaking change is the crate hierarchy restructure. If your project depended on
individual Fabryk sub-crates directly, update your Cargo.toml to use the umbrella crates:
# Before (0.1.x)
fabryk-core = "0.1"
fabryk-content = "0.1"
fabryk-fts = "0.1"
fabryk-graph = "0.1"
fabryk-vector = "0.1"
# After (0.2.0)
fabryk = { version = "0.2", features = ["full"] }The fabryk-mcp umbrella follows the same pattern. Vendor-specific crates
(fabryk-auth-google, fabryk-gcp) remain separate and are versioned independently.
The Rust edition upgrade to 2024 and MSRV bump to 1.85 require Rust 1.85 or later in your
toolchain. Run rustup update stable if you are on an older toolchain.
0.1.0
Full Changelog: https://github.com/oxur/textrynum/commits/0.1.0