Transform
A named, typed state transition. It does one piece of work and exposes where state changes.
Transform<I, O>
Field note 00 / Executable architecture
Explore boundaries, compare architectures, and exercise failure paths with typed transforms before attaching models, tools, and application code. Then run the same graph and inspect what happened.
CMG stays domain-free. The core vocabulary is deliberately small enough to investigate, compose, and verify.
A named, typed state transition. It does one piece of work and exposes where state changes.
Transform<I, O>
Every intermediate input and output remains inspectable after a run.
TraceStep[]
Decide whether the final state passed, failed, partially passed, or remains unknown.
EvaluationResult
Accept, retry, adjust, reject, or return a domain-defined next action.
FeedbackAction
Start with a structured examination, not an automatic generator. The builder decides which boundaries matter; CMG makes those decisions executable and inspectable.
What enters the system, and what evidence makes an output acceptable?
Which named transformations turn the input into progressively more useful state?
Which work belongs in ordinary code, and where is model reasoning genuinely required?
What typed value moves between responsibilities, tools, models, and humans?
Which caller-defined relationships must survive the full composition?
Should the completed run accept, retry, adjust, reject, or request human input?
Method boundary / CMG does not scan a product idea automatically. The builder projects the problem into transforms, connections, evaluation, and feedback; CMG supplies the executable object.
Use the same evidence-synthesis problem to inspect four candidate patterns. These are architecture hypotheses—not performance claims. Signals arrive only after execution.
The architecture definition and the executed graph are the same object. The terminal view derives from that graph and its completed trace—there is no separately maintained whiteboard diagram.
Graph
[Reading] ─┬─▶ [Physics] ─┐
└─▶ [Empirical] ─┴─▶ [Reconcile]
Run
physics 40 → 125
empirical 40 → 145
reconcile [125,145] → 20
evaluation fail
feedback retry
Checked-in values from repository example 12. Feedback returns an action; the caller decides whether to run again.
A transform can return a valid value while the relation between transforms is wrong. Record the relation you expect, then inspect whether the run preserved it.
Every generated claim maps to at least one retrieved source.
Well-formed prose passes local checks while unsupported claims cross the evidence boundary.
Analysis must consume the normalized output produced earlier in the run.
Each function accepts its input, but the graph connects analysis to the unnormalized branch.
Independent specialists contribute distinct evidence before reconciliation.
Two branches reuse the same source, creating apparent consensus without independent support.
The graph makes relations inspectable. The evaluator decides which relations matter.
Architecture sketches make tradeoffs discussable; executed traces make them measurable. Missing evidence stays missing—it is never replaced with a confident score.
usefulFlowScore(quality, cost); callers decide what quality and cost mean.
Informs evaluation and feedback.
judge → actInform error and sensitivity.
error × sensitivityInforms useful output and bottlenecks.
Φ = Q / CProvides types, traces, and deterministic interfaces.
I → OcreateTransform(...)
createModelGraph(...)
graph.run(...)
You should not need to learn the theory before you can inspect the system.
TypeScript and Python capabilities ship at parity. This concise specimen is adapted from the repository’s core pipeline and terminal APIs.
import { createModelGraph, createTransform } from "@composable-model-graph/core";
import { renderRun } from "@composable-model-graph/terminal";
const trim = createTransform<string, string>({
id: "trim", name: "Trim",
run: (input) => input.trim(),
});
const words = createTransform<string, string[]>({
id: "words", name: "Split words",
run: (input) => input.toLowerCase().split(/\s+/),
});
const graph = createModelGraph({
id: "pipeline", name: "Core pipeline",
transforms: [trim, words],
});
const run = await graph.run(" Hello Model Graph ");
console.log(renderRun(graph, run));
from composable_model_graph import (
create_model_graph, create_transform,
)
from composable_model_graph.terminal import render_run
trim = create_transform(
"trim", "Trim", lambda text, ctx: text.strip()
)
words = create_transform(
"words", "Split words",
lambda text, ctx: text.lower().split(),
)
graph = create_model_graph(
"pipeline", "Core pipeline", [trim, words]
)
run = graph.run(" Hello Model Graph ")
print(render_run(graph, run))
Use the architecture workbench to expose boundaries before implementation—then use the same graph to execute, inspect, evaluate, and improve the system.