Definitions of core concepts in the Humainary Substrates API.
This glossary is organized into two layers. Core Concepts are what most users need to build with Substrates. Advanced Concepts cover dynamic topology, lifecycle management, identity internals, and framework extension — learn these when you need them, not before.
These are the types most users interact with directly.
-
Cortex: The factory entry point for the Substrates framework. Provides methods for creating circuits (
circuit()), hierarchical names (name()), scopes (scope()), slots (slot()), and states (state()). Access viaSubstrates.cortex(). -
Circuit: The central processing engine that manages data flow with strict ordering guarantees. Each circuit owns exactly one processing thread (virtual thread) that sequentially processes all emissions. Manages two internal queues:
- Ingress Queue: Shared queue for emissions from external threads (requires synchronization)
- Transit Queue: Local queue for emissions from within the circuit thread itself (lock-free, priority over ingress)
The transit queue enables cascading emission ordering where nested emissions complete before processing the next external emission, ensuring causality preservation and enabling neural-like signal propagation.
-
Conduit: A pipe factory and source. Created using
Circuit.conduit()(type inferred from context) orCircuit.conduit(Class)(explicit type witness). Pools named pipes by name, ensuring stable identity and routing guarantees. ImplementsPool<Pipe<E>>— useconduit.get(name)to retrieve a named pipe andconduit.pool(fn)to create cached derived views (domain-specific wrappers or flow-enabled pipes). -
Pipe: An emission carrier responsible for passing typed values through pipelines. Extends the
Substrateinterface, providing identity viasubject(). Created viaCircuit.pipe(Receptor)orCircuit.pipe(Name, Receptor)to wrap callbacks for receiving emissions. Providesemit(E)for sending values. -
Cell: A circuit-owned, initialized, single-slot state holder with safe publication. Created via
Circuit.cell(E)with a non-null seed value (the no-argument factory was removed in 2.9). Exposespipe()for queued updates andget()for the current published value;get()never returnsnull. Updates execute on the owning circuit's worker thread; readers may callget()from any thread. Use Fiber/Flow upstream to compute the value to publish — Cell is the end of the pipeline, not a transformation stage. Applications that need "no value yet" semantics should model that as a domain value such asOptional<E>or an explicit sentinel. -
Port (2.9): A circuit-owned, initialized state slot that grants queued mutation authority without exposing direct read access. Created via
Circuit.port(E)orCircuit.port(Name, E). Exposesreplace(E),update(UnaryOperator<E>),update(A, BiFunction<E, A, E>), andemit(Pipe<? super E>)— all queued, all callable from any context. Holders can evolve state but never observe the current value. Transform functions run inside the owning circuit context; a null/absent return is treated as a framework-detected contract violation and surfaced as aFaultcarrying the port's subject. Use Port when a module needs mutation authority without read authority (principle of least authority). -
Pin (2.9): A circuit-owned, initialized state handle that grants immediate inspect/mutate access confined to the owning circuit context. Created via
Circuit.pin(E)orCircuit.pin(Name, E). Exposesget()andset(E), both synchronous and both raisingIllegalStateExceptionwhen invoked from any context other than the owning circuit's worker thread. Safety comes from confinement, not synchronization. Use Pin when circuit-local code needs synchronous "set X, then read X on the next line" semantics, or when mutable in-place objects must be updated under circuit-context confinement. A Pin handle may be emitted as a value through any pipe, but only the owning circuit can dereference it. -
Ticker: A circuit-owned periodic emitter. Created via
Circuit.ticker(Duration, Pipe)orCircuit.ticker(Name, Duration, Pipe). Drives a gap-free, monotonically increasing tick sequence (starting at zero) into the target pipe at a fixed rate: scheduling error does not accumulate, and a stall longer than one interval re-anchors the schedule rather than firing a catch-up burst. ExtendsResourcefor lifecycle management; closing the ticker (or its owning circuit) stops emissions. -
Name: A hierarchical naming system using dot-separated segments (e.g.,
parent.child.grandchild). Names are immutable, interned, and use identity-based equality (==). Created viaCortex.name()methods from strings, classes, enums, members, or iterables. ExtendsExtentfor hierarchical traversal. -
Subject: A hierarchical reference system that provides identity, name, and state for every component in the Substrates framework. Every substrate component (circuit, conduit, pipe) has a subject enabling precision targeting and observability. Parameterized by its owning substrate type for type-safe subject extraction.
-
Fiber: A per-emission operator pipeline preserving emission type. Created via
Cortex.fiber()orCortex.fiber(Class). Supports filtering (guard,dropWhile,takeWhile,change,edge,route,when), comparison-based filtering (above,below,min,max,range,clamp,deadband,high,low,hysteresis), sampling and rate control (every(int),every(Duration),chance,skip,limit,inhibit,delay), stateful operators (diff,distinct,distinct(int),reduce,integrate,rolling,pulse,relate,steady,tumble), and observation (peek,replace,tee). Composes with another fiber viafiber(Fiber<E>)and materializes to a target viapipe(Pipe<E>). -
Flow: A left-to-right composition surface for type-changing stages and output-side recipes. Created via
Cortex.flow(),Cortex.flow(Class), orCortex.flow(Fiber). Providesmap(Function<O,P>)to append a downstream type transformation (returningnullfilters the emission),scan(Supplier, BiFunction)for state-as-output folds over immutable/effectively immutable state,scan(Supplier, BiFunction, Function)for projected stateful type-changing folds,window(int)for count-bounded andwindow(Duration, int)for time-bounded rolling temporal windows over surviving output values,fiber(Fiber<O>)to attach a same-type per-emission recipe at the output side,fiber(Function<Subject<?>,Fiber<O>>)for a subject-aware fiber factory evaluated per attachment,flow(Flow<O,P>)andflow(Function<Subject<?>,Flow<O,P>>)for first-class composition with another flow or a subject-aware flow segment, andpipe(Pipe<O>)to materialize the pipeline against a downstream pipe. -
Window: A callback-scoped, read-only rolling view emitted by
Flow.window(int)orFlow.window(Duration, int). Exposes the most recent surviving output values in encounter order and supportsfirst,last,prefix,suffix,slice,skip,trim,reverse,size,isEmpty, and eager terminal operations (forEach,all,any,none,count,fold,reduce). Iterators, spliterators, and streams are intentionally not exposed — a Window must be consumed during the callback that observes it; copy values if they must be retained or forwarded. -
Receptor: A callback interface for receiving emissions. Domain-specific alternative to
java.util.function.Consumerwith a guaranteed non-null contract. Used to create receptor pipes that receive emitted values. Provides factory methods likeReceptor.of()andReceptor.NOOP. -
Reservoir: An in-memory buffer that captures emissions along with their subjects. Created via
Source.reservoir(). Providesdrain()to retrieve accumulated emissions as a stream ofCaptureobjects. ExtendsResourcefor lifecycle management. Primary tool for testing and diagnostic observation. -
Sink: A pool of named pipes (
Pool<Pipe<E>>) whose destination is a single endpoint pipe fixed at creation — the output-closed dual of aConduit. Each emission into a channel is minted into aCaptureat that channel and forwarded to the endpoint. ASubstrate, not aResource(noclose()). Created viaCircuit.sink(endpoint).
-
Subscriber: A component that dynamically subscribes to sources and registers downstream pipes via a
Registrar. Created viaCircuit.subscriber(), making it a child of the circuit in the subject hierarchy (subject path:circuit-name.subscriber-name). This establishes that the subscriber observes the ordered view provided by that circuit's single-threaded processing. Invoked lazily on first emission to discovered named pipes, enabling adaptive topologies that respond to runtime structure. ExtendsResourcefor lifecycle management. -
Subscription: A lifecycle handle returned when subscribing to a source. Provides
close()to unregister downstream pipes. Cancellation uses lazy rebuild — changes take effect on the next emission, not immediately. -
Registrar: A temporary handle passed to subscribers during their callback, allowing them to attach downstream pipes. Provides
register(Pipe)andregister(Receptor). **Temporal contract **: Only valid during the subscriber callback — attempting to use it afterwards violates the temporal contract. -
Source: An interface that allows components to expose their events for subscription. Manages the subscription model and connects subscribers to named pipes with lazy rebuild synchronization. Implemented by Circuit, Conduit, and Tap.
-
Lookup: The abstract base for name-indexed retrieval. Defines the single operation
get(Name): return the instance for the given name (creating it on first access for caching implementations). Implementations are thread-safe for concurrent retrieval. Extended by bothPool(composable derived views) andBank(ownership semantics). -
Pool: A composable name-based view extending
Lookup. Inheritsget(Name)and addsget(Subject),get(Substrate)convenience overloads andpool(fn)for creating cached derived views that apply a transformation function per name.Conduit<E>extendsPool<Pipe<E>>. -
Bank: A closeable name-indexed holder for same-kind named resources. Created via
Circuit.bank(Class)orCircuit.bank(Class, Routing). ExtendsLookupandResource:get(name)materializes a conduit on first access and caches it; closing the bank closes all conduits it has materialized. Unlike a Pool (a derived view over an existing conduit's pipes), a Bank creates and owns its conduits.getis open-required — calling it after the bank has been closed throwsFault. -
Tap: A transformed view of a conduit's emissions. Mirrors the named pipe structure of its source. Three overloads:
Conduit.tap(Function)(mapper receives the tap's target pipe and returns a source-compatible pipe),Conduit.tap(Flow)(concise form oftap(flow::pipe)for type-changing transformations), andConduit.tap(Fiber)(concise form oftap(fiber::pipe)for type-preserving per-emission processing). ExtendsSourcefor subscription andResourcefor lifecycle management. Must be closed when no longer needed to unsubscribe from the source conduit.
-
Substrate: Base interface for all substrate components that have an associated subject. Self-referential and parameterized by its own type, enabling typed subject extraction where
substrate.subject()returnsSubject<ThisSubstrateType>. -
Id: A unique identifier component of a Subject. Ensures each component can be distinguished even if names are identical. Uses reference equality (
==) for O (1) comparison. -
Extent: An abstraction of hierarchically nested structures. Provides traversal methods like
enclosure()(parent),extremity()(root),depth(),fold()/foldTo(),path(), andwithin(). Implemented by Name, Subject, and Scope. -
State: An immutable collection of named slots containing typed values. Supports persistent updates where operations return new instances. Provides
state(Name, value)for adding slots,value(Slot)for lookup,compact()for deduplication, and iteration/streaming over slots. -
Slot: An opaque interface representing a variable within a State. Provides both a query key (name + type) and a fallback value. Matching occurs on slot name identity AND slot type. Created via
Cortex.slot()methods for boolean, int, long, float, double, String, Name, State, and Enum.
-
Resource: A lifecycle interface for explicitly releasing resources and terminating operations. Provides an idempotent
close()(queued, non-blocking — submits cleanup and returns immediately) andcloseAwait()(blocking — suspends the caller until cleanup has executed; MUST NOT be called from the circuit thread). Implemented by Circuit, Conduit, Bank, Subscription, Reservoir, and Subscriber. Does not extendAutoCloseableas most resources have indefinite lifetimes. -
Scope: A structured resource manager that automatically closes registered assets in reverse order (LIFO), enabling RAII-like lifetime control. Implements
AutoCloseablefor try-with-resources. Providesregister(Resource)for scope-lifetime resources,closure(Resource)for block-scoped resources, and hierarchical child scopes viascope(). ExtendsExtentfor parent-child relationships. -
Closure: A utility interface for scoping work performed against a resource. Provides block-scoped resource management where
consume(Consumer)executes the consumer with the resource then automatically closes it. Single-use - once consumed, the closure is exhausted. Temporal contract: Only valid during the consume callback. -
Capture: A record of an emitted value from a named pipe with its associated subject. Produced by Reservoirs and Sinks. Provides
emission()for the value andsubject()for the pipe identity. Used for testing, debugging, telemetry, and replay.
- Current: Represents the execution context (thread, coroutine, fiber) from which substrate
operations originate. Obtained via
Cortex.current()in a manner analogous toThread.currentThread(). Current is an interned identity token for an execution context and may be retained for identity comparison and immutable subject inspection.
Several Substrates interfaces follow temporal contracts — they are only valid within specific execution scopes and must not be retained or used outside those scopes:
- Registrar: Valid only during
Subscribercallback. Retain the pipes you attach, not the Registrar. - Window: Valid only during the receptor or Fiber callback that observes it. Copy values during the callback if they must outlive it.
- Closure: Valid only during
Closure.consume(Consumer)callback. Single-use, resource closed when callback returns.
Violating temporal contracts leads to undefined behavior. The framework marks temporal interfaces
with the @Temporal annotation.
Type-preserving per-emission operators live on Fiber; type-changing composition, including
stateful folds via scan and rolling windows via window, lives on Flow. Both are first-class
values built from the cortex and materialized against a target pipe via pipe(...).
// Build a recipe and attach it to a target pipe
cortex.fiber(Integer .class)
.
guard(x ->x >0) // filter
.
diff() // deduplicate
.
limit( 10) // backpressure
.
pipe(target);- Purpose: filtering, routing, fan-out, deduplication, sampling, comparison, and stateful per-emission processing
- Type behavior: input and output share the same type (e.g.,
Integer→Integer) - Materialization:
fiber.pipe(target)produces aPipe<E>whose emissions feedtarget
// Map I → O on the output side, then attach a same-type fiber recipe
cortex.flow(Integer .class)
.
map(i ->"value:"+i )
.
fiber(cortex.fiber (String.class).
diff() )
.
pipe(sink);- Purpose: append a downstream type transformation, run a stateful type-changing fold, publish an immutable running state directly, attach Fiber recipes at the output side, emit rolling windows, or compose flows
- Operations:
map,scan,window(int),window(Duration, int),fiber(Fiber),fiber(Function<Subject,Fiber>),flow(Flow),flow(Function<Subject,Flow>),pipe - Materialization:
flow.pipe(target)produces aPipe<I>that runs the pipeline ahead oftargetontarget's circuit
All stages execute on the circuit's worker thread after emissions are dequeued, providing
single-threaded execution guarantees. Stateful Fiber operators (diff, distinct, reduce,
limit, integrate, rolling, ...), Flow scan state slots, and Flow window rolling buffers
maintain per-attachment state without synchronization.