This website is meant to be read and understood quickly by humans, but is only fully parsable, on a technical level, with the aid of an AI system. Read why →
Loop MMT

The Gifts — a developer's guide

Part one — composing what already ships

Start here. Everything below is free, MIT-licensed, and runs today. First find the tool you need by the shape of your problem, then learn the grammar that snaps tools together.

Find a tool by what you need

Scan for the shape of your problem. Each tool links to its own page; every tool here is free, MIT-licensed, and has zero required dependencies beyond what its Stack names.

source — brings data in (a file, a feed, a fetch)

ToolWhat it doesIts edge (the honest limit)
callsigns CallsignsMemorable IDs, Safe by ConstructionA callsign is a memorable, SAFE identifier — not a guaranteed-unique one. The hash makes an accidental collision astronomically unlikely, but “unlikely” is not “impossible”: if your correctness depends on uniqueness, pair a callsign with a real uniqueness source (a timestamp, a sequence, a registry that rejects duplicates). It buys memorability and paste-safety, not a uniqueness authority.take it →
census CensusMarker Census, Buried Ones FlaggedIt's a text scan, not a parser — it finds markers by pattern, so a marker written in a syntax it wasn't told about is a marker it won't see. You define the patterns; their completeness is your call.take it →
declare declareNamed Pipeline ScoreIt SAVES a pipeline; it does not VALIDATE it (that's typecheck) and does not RUN it (that's a runner). declare will faithfully write down a score that would not typecheck — it claims only that the pipeline is recorded, never that it is runnable. With --manifest it flags any stage that isn't a declared tool, saving the score anyway and flagging it, never silently dropping a stage.take it →
fanout Branch SplitterHow Do You Split One Input Into Declared Branches?fanout splits one input into declared branches; it does not run them, order them by any policy but declared order, or judge whether a branch name is meaningful — it only refuses an undeclared, empty, duplicate, or ill-formed branch.take it →
gitlog GitlogGit History On A PipeIt reports exactly what git reports — it's only as complete as the history you point it at. A shallow clone gives you a shallow answer, faithfully.take it →
loop21-component-factory loop21:component-factoryLogic Components as Composable DataThe factory declares components; it does not run them. An emitted spec is a validated description, not a live object — turning a spec into behavior is the consumer's job, and this tool makes no claim about whether any downstream runner implements a kind correctly. It guarantees the spec is well-formed and catalog-valid, not that anyone honors it.take it →
mint MintIDs That Are Never ReusedIt guarantees no reuse within the one ID store you point it at. Two independent stores that don't know about each other can still collide — single source of truth is your job.take it →
port portComposition Port-Verb DeclarationIt verifies a declaration is consistent with itself — manifest field vs the tool's own --port flag — not that the declared verb is true of the tool's actual behavior. A tool can honestly declare 'filter' in both places and still behave like a transform in its code; proving a verb against real behavior is a deeper, undecidable-in-general question this tool does not claim to answer.take it →

filter — keeps or drops, shape unchanged

ToolWhat it doesIts edge (the honest limit)
clause-trellis Clause-TrellisWhich Two Clauses in Your Prompt Fight?clause-trellis finds contradictions you DECLARED, over a closed set of decidable dimensions (numeric ranges and categorical values). It does not read intent, meaning, tone, or the natural-language text of a clause — if two sentences contradict in spirit but you did not declare the shared dimension, it will not see it. Silence means 'no declared contradiction,' which is necessary, not sufficient. It finds the conflicts you wrote down; it does not understand the prompt.take it →
confessional Your Prompt Goes to ConfessionWhat Does Your Prompt Quietly Fail to Constrain?confessional CONFESSES the constrainable dimensions your prompt left open, from a declared checklist — it cannot find a gap outside that checklist, cannot tell you whether an open dimension matters for your task, and cannot make your prompt complete. It confesses; it does not audit. Its deepest edge: it cannot find the gap you never named.take it →
conflict ConflictA Broken Merge Can't LandThis is a check, not an immunity — it protects you only when it is RUN, so wire it into a hook or CI rather than trusting a human to remember. And it detects the standard git marker triad; a tool that uses different markers needs a different pattern. Visibility, not immunity.take it →
derived derivedDerived-File Staleness Checkerthis checks STALENESS (committed vs a fresh build), not CORRECTNESS: a green means the file matches what the command emits right now, never that the command or its output is right. It runs your build command, so only point it at a command you trust.take it →
gauntlet gauntletFault-Injection Check-Testergauntlet tests whether a check CATCHES the ONE fault you inject, not whether the check is correct in general: a HELD proves the check fired on this one broken input, never that it catches every fault. It runs your check command, so only point it at a command you trust. It only ever copies the target — it never modifies your original file.take it →
isvalidcsscolor IsvalidcsscolorIs This String A CSS Color?It validates a DEFINED subset — the colors people actually type. It deliberately does not accept hwb()/lab()/lch()/oklab()/oklch()/color()/color-mix()/relative-color syntax/system colors, and it rejects the CSS-wide keywords inherit/initial/unset/revert (which are not colors). In a browser, CSS.supports('color', str) is the full ground truth; this trades that breadth for a tiny DOM-free core you can read in one sitting.take it →
loop21-verifyskin Skin Config ValidatorIs This User Config Safe To Apply?It keeps 'wrong' and 'unknown' apart: a bad type/range/injection is an ERROR, an unknown field is a dropped WARNING (forward-compat), a missing optional field is silent. The `string` type is NOT stylesheet-sanitized — it type-checks and length-caps only; use `cssvar` (the type with the injection allowlist) for anything headed into a style surface. The named-color allowlist is conservative (unknown names rejected, not guessed) and the cssvar check is a safe-character GRAMMAR, not a full CSS value parser — it proves the value can't break out of a declaration, not that it is meaningful CSS. The schema is YOURS: a malformed schema throws (programmer error); only the config is treated as untrusted and reported-not-thrown.take it →
plumb PlumbStatus Board That Won't LieIt checks the witness exists and agrees, never that the witness is the right one. Point it at the wrong file and it'll happily pass — choosing a meaningful witness is your job.take it →
scrub ScrubCatch a Secret Before It Shipsscrub matches KNOWN secret shapes. A clean result means no known shape was found here — it is NOT proof the text is secret-free: a novel token format, a secret split across lines, or a home-rolled scheme passes clean. It is a smoke alarm, not a vault — a hit is real, a clean scan is the absence of a known shape, never a certificate. Because it matches shapes it also flags EXAMPLE secrets (a documented token, its own fixtures) — the honest ceiling working, not a bug; vouch for a line you know is safe with scrub-allow.take it →
trellis The TrellisTwo-Way Consistency, LocalizedIt checks that your constraints are consistent WITH EACH OTHER, never that they are the ones you meant. Hand it the wrong constraints and it will faithfully find them consistent — choosing constraints that capture what you actually care about is your job.take it →
typecheck typecheckComposition TypecheckIt validates the PORT type — can the pipe carry data at all — NOT the RECORD shape. Two tools can both speak JSON-lines so the ports agree, while the records one emits are not the records the other expects; that pipeline typechecks clean here and still fails at runtime. typecheck flags the record-shape layer as unproven and never asserts semantic fit. A slug not in the manifest is reported UNRESOLVED, never guessed.take it →
verify VerifyCheap Re-Check, Never TruthFRESH means the byte-truth inputs are unchanged, never that the fact is TRUE (⊢, not ⊨). It re-checks the ground you named — name too few inputs and a real dependency can move without tripping STALE. Byte-truth facts only; live facts (prices, who's CEO) can't be cheaply certified.take it →
weir weirRun a Pipeline Under a Budget You Can Actually Meterweir cuts the flow it can SEE — the command's stdout, line by line. It does not cap the command's own internal resource use (a command that loads 10 GB before its first row is past weir's reach until that row appears), it does not sandbox the command, and a wall-time cut is real but not reproducible — the same input can cut at a different row on a slower machine. It governs flow at the pipe; it does not make your command safe.take it →

transform — reshapes one thing into another

ToolWhat it doesIts edge (the honest limit)
doppelganger Your Prompt's Evil TwinWhere Does One Small Rephrase Quietly Flip Your Prompt's Output?doppelganger PROPOSES candidate twins and MEASURES textual divergence, for hardening your own prompt — it does not run your prompt, prove a flip is harmful or that a twin "worked", find a rephrase it has no rule for, or make your prompt safe to ship. A hardening tool, not a jailbreak factory.take it →
dwell DwellWhen You Commit Is What You ChooseIt is the deterministic router only: given (entry, reverse, n, k) the exit is a fact, but it does NOT decide when to stop deferring — that judgment (the reversal) is yours. k <= n is a wall (you can't quantize a loop of n ticks into more than n exits); k > n is refused, not rounded.take it →
exif-parser EXIF ParserWhat Did The Camera Record?It reads metadata only — no pixels, thumbnails, or MakerNote (vendor-specific: surfaced as raw bytes, never guessed). It follows IFD0 -> Exif-IFD -> GPS-IFD, not IFD1/interop IFDs. It does not strip or rewrite EXIF, and malformed input throws. GPS is left as raw rational components (GPSLatitude as three rationals + a ref) — it does NOT collapse them into a signed decimal degree, because baking one interpretation into the parser is a presentation choice you should own; compose the decimal yourself.take it →
forest-title-fit forest-title-fitNever-Clip Title SizingIt sizes to the measure() you inject — only as accurate as your measurer (a webfont still loading measures as its fallback). It searches integer sizes and breaks on whitespace, not hyphens; a single word wider than the box overflows visibly, by design. It computes sizes and lines; the caller renders.take it →
l21x-snapshot l21x-snapshotBrowser Save LayerIt persists structure, not identity — you supply ids and timestamps; snapshots are base64 (not compressed, not encrypted). It's a layer that hands you strings, not a store: it never touches localStorage, the disk, or the DOM itself.take it →
legible Text Legibility GaugeReadable Text, or Machine Rubble?legible is a heuristic, not a verdict, and it detects control-character rubble — NOT wrong encoding. Mojibake (valid bytes, wrong charset) is still printable characters, so it reads `readable` even though no human can read it: a `readable` means “not control-char rubble,” never “correctly decoded.” It does not decode, validate, or understand the text, and never proves it correct or meaningful. It is a gauge you read, never a gate you route on.take it →
markdown MarkdownOne Source, Two Honest ShadowsA bounded, deliberate Markdown subset — headings, lists, blockquote, fenced code, and inline strong/em/code/link/hard-break — not CommonMark, and small on purpose (tables, nested blockquotes, and footnotes are out of scope by design, not by accident). The browser toDOM emitter of the original it's ported from is left out of this runtime-agnostic standalone; the two shadows shipped are HTML and plain text.take it →
ratchet-inline-mime Inline MIME ParserWhat's Actually Inside This Email?It parses, it does not validate — a message with a missing closing boundary or a header with no body is parsed as far as it reasonably can, never thrown at, so the tree reflects what was there rather than what should have been. Charset support is honest about its scope: utf-8 (full multibyte) and the byte-preserving ascii/iso-8859-1/windows-1252 family decode faithfully; ANY OTHER charset falls back to utf-8 rather than transcoding from native tables — exotic legacy charsets are the edge. An unknown Content-Transfer-Encoding is treated as identity. Header values are RFC-2047-decoded in the `headers` map only; `rawHeaders` keeps the ordered, undecoded originals for anything that must see the wire bytes.take it →
ratchet-pdf-dict PDF Dictionary-Text ExtractorWhat Text Does This PDF Store?It splits its contract by scale, on purpose: document-level failure (not a PDF, bad input) THROWS like its ratchet-pdf-text twin, but a single malformed value is RECORDED as {malformed, reason} and the walk continues rather than losing the good fields after it — a malformed value is stamped, never returned as clean. It reads the TOP-LEVEL dictionary of each object: a /V or /Contents in a nested sub-dict, or a value inherited through /Kids, is not a target. It resolves an indirect /V one level only. It returns the string as WRITTEN — no /Encoding or /ToUnicode CMap mapping, correct for WinAnsi and honestly wrong for a subsetted CID font. It does not decrypt, decode /ObjStm or xref streams, or repair a broken file.take it →
ratchet-pdf-text PDF Text ExtractorWhat Text Does This PDF Draw?It returns the string operands as WRITTEN — it does NOT map character codes through a font's /Encoding or /ToUnicode CMap, so it is correct for the common WinAnsi/standard-font case and honestly wrong for a subsetted CID font (glyph-index bytes, not characters). It gives drawn strings in stream order, not a visual reflow — no positional layout or reading-order reconstruction. FlateDecode content is the common case and zlib inflate is not in the browser's zero-dep surface, so a compressed stream is SURFACED as raw bytes and decoded only if you pass an inflate function (Node: zlib.inflateSync; browser: pako) — never faked. It does not decode /ObjStm, xref streams, encryption, or images; malformed input throws.take it →
ratchet-png-text PNG TextWhat's Hidden In That PNG?It reads TEXTUAL metadata only — no pixels, IHDR, palettes, or gamma. It does NOT inflate zTXt / compressed-iTXt on its own (zlib isn't in the browser's dependency-free surface): such records come back with compressed:true, text:null, and their raw compressedText bytes, decoded only if you pass your own inflate function. And it does not repair a bad file — malformed input throws, it never guesses.take it →
reltime ReltimeRelative Time That Refuses To LieIt renders in UTC and is a recency label, not a locale-aware or timezone-shifting formatter, and not a full date library. The fixed minute/hour/day/week bands are by design — the value is the refusal to fabricate, not configurable granularity.take it →
sha256 Sha256Sync Hash That Matches Your BackendIt's a hash, not an HMAC and not encryption — it proves two inputs match, keeps no secret, and is not a password KDF. A from-scratch port for portability, not a hardened crypto library: where a vetted native lib is available and async is fine, prefer it.take it →
sudoku SudokuA Solver That Shows Its WorkIt only makes FORCED moves — it reasons, it does not search or backtrack, so a puzzle needing a technique above x-wing returns ceiling-hit (a difficulty read), not a guessed fill. And ‘broken’ fires when reasoning empties a cell; a contradiction sitting between two givens no technique touches reads as ceiling-hit, because the solver reasons about the puzzle rather than front-validating your input.take it →
template The Mail-Merge That Won't LieHow Do You Fill A Prompt Template Without It Silently Lying?template fills the {{variables}} your template declares from the record you give it, and refuses (naming the blank) when a required variable is missing; it does not judge whether the filled prompt is correct, meaningful, or safe, and it is not a template language — no logic, loops, or conditionals.take it →
the-oracle The OracleWhich Prompt Variant Did Run #4173 Get? Make It a Fact You Can Recompute.the-oracle makes an assignment reproducible and auditable; it does not make it fair, uniform, or unbiased -- a chosen (seed, moment, n) can skew which variant wins, and reproducing a skewed pick reproduces the skew. It does not run your prompts, call any model, score a variant, or tell you which is better. It decides which variant, reproducibly; it does not decide whether the experiment was sound. Reproducible, not random.take it →
tracebus TracebusNothing Moves Without a ReceiptIt enforces the topology you declare and records every hop; it does NOT invent routes for you (an unrouted packet is a fault, by design) and its ids are v4-shaped for correlation, not cryptographic (Math.random). request/response is opt-in per bus via { requestResponse: true } — the bus name carries no special meaning.take it →
vclock VclockCausal Order, Not Wall-Clock TimeIt orders events that share an actor namespace. Two records whose actor sets never overlap read as concurrent by construction — which is correct, but only useful if your actors are named consistently across the stream.take it →

fold — many things into one (a merge, a reduce, a join)

ToolWhat it doesIts edge (the honest limit)
amber amberFile-Set Fixity Sealerit proves IDENTITY, not BYTES: a green verify means every sealed file still hashes to what it did at seal time, never that the files are backed up — keep them in git or a zip if you need the bytes themselves. Content-addressed via git-style blob SHAs computed in-process (no git shell-out).take it →
cruise CruiseFeature Inventory, No HallucinationsIt's a text scan with a declared pattern set, not a language parser — a framework or idiom it wasn't told about is a fact it won't see (it fails safe: a real fact left out, never a fabricated one put in). Route/call matching is literal, so a served '/x/:id' and a called '/x/42' are different strings and a live parameterized route can read as headless. Treat headless as 'look here,' not 'delete this.'take it →
excavation The ExcavationCoverage-Provable Reading ContractThe standalone driver is proven in a tree that carries the builders and their helpers; pointed at a bare stranger tree it fails loudly on the missing imports rather than pretending. Full standalone independence is the next build beat — earned against a real foreign fixture, not asserted. The gap is documented in the driver header, not papered over.take it →
grain GrainStructure Smell TestIt's a smell, not a proof — a smoke alarm, not an arson investigator. Great for staleness and homogenization drift; not a data-rot or dead-link checker.take it →
hunkhole HunkholeThe Change Git HidesEvery hit is a QUESTION, not a verdict — a symbol you renamed or retired reads exactly like one that was reverted away, so hunkhole hands you the finite list and you rule on each. And a clean run is NOT a clean bill: it sees NAMED TOP-LEVEL definitions only, so a hunk reverted inside a surviving function body is invisible to it. Visibility, not immunity.take it →
jsonl-diff JSONL-DiffWhat Changed Between Two Runs?jsonl-diff compares STRUCTURE, not MEANING. A reported change may be cosmetic (1 vs 1.0, "a,b" vs ["a","b"]) and an unreported match may still be wrong — semantic equivalence it will miss is a difference here. A human reads the diff; the tool only makes the change visible and exact. It tells you two records differ; it cannot tell you the difference matters, is correct, or is safe.take it →
junction Branch MergerHow Do N Branches Fold Back To One?junction merges declared branch-records into one under a declared policy; it does not choose the policy for you, run the branches, or resolve a value conflict the policy leaves ambiguous — it refuses (non-zero exit) when no policy is declared or the policy cannot merge cleanly.take it →
map mapComposition MapIt renders the TYPE-level map — whether the ports agree so the pipe can carry data at all — not whether the RECORDS fit. A transform emitting {event} records maps clean into a filter expecting {file} records and fails at runtime; map flags that semantic layer as unproven and never asserts it.take it →
palimpsest PalimpsestWhich Parts of My Prompt Actually Stuck?palimpsest measures SURVIVAL, not QUALITY. A line that survived every draft is load-bearing to the author — not thereby correct, good, or necessary. A mistake copied faithfully through every version survives with rate 100% and lands in the core. Persistence is evidence of intent, never of merit. A human reads the core and decides what it means; the tool only makes survival visible and exact.take it →
parity ParityParity Matrix, Gaps SurfacedHAS means exactly one thing: a mark normalizing to this key was DECLARED for this thing — never that the feature works or behaves like the next column's. Parity is a presence fold, not a behavior test; every cell carries predicate 'declared-present', and any row where two or more things HAS a mark is flagged needs-behavior-check. It surfaces where declarations disagree; it does not verify the declarations are true.take it →
quorum Ask Three, Trust The OverlapHow Do You Turn N Model Answers Into One You Can Trust?quorum counts agreement; it does not judge correctness. N sources can agree and all be wrong — a majority can be a shared blind spot. A quorum means "this many independently landed here", never "here is right". It does not call the models for you — you bring the answers, it folds them. Concordance, not truth.take it →
reading-oath Make The AI Prove It Read The Whole ThingHow Do You Know The Model Read All Of Your Context, Not Just Some Of It?reading-oath proves COVERAGE — that every shard of your context was seen — not COMPREHENSION; a reader can cover every shard and still misunderstand it. It also trusts the reader to report the ids it actually read: it detects a skipped shard, not a lie about a read one.take it →
timeline timelineTimeline Artifact Validatorit is a PRESENCE checker, not a CORRECTNESS oracle: it confirms a scale is declared and self-consistent with the ops used, never that the declared level is the right one, and it does not prove your renderer is a pure fold — that runtime property stays yours to prove.take it →
timesheet TimesheetHow Many Hours Did That Actually Take?Commit timestamps BOUND work, they do not MEASURE it — a floor-biased model output (⊢), never a measured truth (⊨). It under-counts on purpose (isolated commit = 0, invisible thinking = 0). NOT a timeclock: do not bill a client to the minute or adjudicate hours with it. The --break-gap assumption is printed in every report.take it →
ward WardSelf-Verifying Integrity BadgeYou cannot make a cell lie by asserting harder — but Ward checks the witness agrees, not that you chose the right witness. A meaningful witness is still your call.take it →
worklog WorklogGit History, Grouped by DayIt reports the commit RECORD, not the work — a day with one big commit and a day with ten trivial ones both read as 'commits'; it doesn't measure effort or lines. Grouping is by committer-date and author-name-as-git-records-it, so skewed clocks (rebases, imports) or one person under two names land in the buckets git gives — it reports what git says, it doesn't reconcile identities or fix clocks. Merge commits are excluded by default.take it →

sink — sends the result out (write, deploy, push)

ToolWhat it doesIts edge (the honest limit)
cairn CairnMulti-Store Git RedundancyIt survives store loss, not corruption you push yourself. Push a bad commit and every mirror faithfully keeps your mistake.take it →
conductor conductorProvenance Pipeline Runnerconductor runs the commands you give it — it is exactly as safe as the commands in the score, and it does not sandbox them. Its typecheck is the TYPE-level gate (ports line up so data can flow), not a proof the RECORDS fit or that a stage is correct. It proves the run happened in order with a receipt; it never proves the run was right.take it →
loop21-l21x-snapshot loop21:l21x-snapshotPortable Browser Document PersistenceIt persists and moves documents — it does not encrypt them and it does not resolve merge conflicts. A snapshot is plaintext base64: anyone who has the string has the document. And if two devices edit the same catalog entry independently, the last save wins; this layer has no notion of a conflict, only of the most recent write.take it →

other

ToolWhat it doesIts edge (the honest limit)
switchboard switchboardA Message Bus That Cannot Carry a CommandIt is a bus, not a guaranteed queue and not a command channel. No delivery guarantee and no retry: a read is a logged fact, an unread message stays visible as an orphan until someone reads it, and every message reaches a reader quoted as third-party data, never as the reader's own instruction. Only a human directs.take it →

The one idea

Every tool on this page does one job and tells you exactly where it stops. That honesty is not modesty — it is the whole trick. A tool's edge is what lets it combine safely with the next one. When you know precisely what a tool takes in, what it hands back, and what it refuses to do, you can snap it onto another tool without either of them lying to you. Composition is not a feature we added. It is what falls out when each piece is honest about its own boundary.

So this guide is not a feature tour. It teaches you a small grammar — five kinds of job, two ways to join them — and then gets out of your way. Once you can see the shape of a tool, you will compose your own combinations we never thought of. That is the point.

Five jobs, two joins

Think of data moving left to right through your hands. Every tool here is one of five kinds of job, named by what it does to the thing passing through:

  • source — brings data in. A file, a feed, a git history, a fetch. It starts the line.
  • filter — keeps some, drops the rest. The shape is unchanged; there is just less of it, or it is refused entirely.
  • transform — reshapes one thing into another. Same information, new form.
  • fold — collapses many things into one. A merge, a group-by, a reduce, a summary.
  • sink — sends the finished result out. Write it, deploy it, push it. The line ends.

And two ways to join jobs together:

  • ∘ (in sequence) — the output of one becomes the input of the next. source ∘ fold reads: bring data in, then collapse it. Read it right-to-left like a recipe you follow left-to-right.
  • ⊗ (side by side) — two jobs run independently on the same input, and their results are joined afterward. The catch: joining them must not depend on which one finished first. If the order of the two branches changes the answer, you do not have a clean — you have a race, and you need a rule for merging that does not care about timing.
The five jobs joined in sequence, with one side-by-side pair source transform filter filter fold sink the ⊗ pair — two branches, joined order-independently at the fold
A line of jobs joined in sequence, with one pair in the middle: the transform fans out to two independent filters, whose results the fold rejoins — and the rejoin must not care which filter finished first.

Two you can run

Small, real, copy-and-run. Every tool named here is free and shipped — follow its link for the exact command.

1 · Turn a git history into a daily worklog

gitlog (source) worklog (fold)

gitlog puts your git history on a pipe — one commit per line, as data, not as a wall of text. worklog folds that stream by day, so a week of commits becomes a short "here is what got done, and when" summary. Source in, fold out: the whole pipeline is two honest tools and one join. Neither one knows about the other — that is exactly why they snap together.

The edge to know: both read your git history as it is. They report what the log says, not what you meant — an empty day in the log is an empty day in the worklog. That honesty is the feature.

2 · Gate a structural change before it lands

grain (fold) conflict (filter)

grain is a structure smell-test: it folds a body of work down to a signal about whether its shape is holding together. conflict is a filter with a hard rule — a broken merge cannot land. Put the smell-test in front of the gate and you have a pipeline that refuses to ship structure that has quietly gone wrong. The filter is the boundary; the fold is what tells it when to slam shut.

The edge to know: conflict catches a broken merge — not a bad idea you cleanly committed. It guards the mechanics of landing, not the wisdom of what you landed. Know which boundary a tool actually holds, and you will never be surprised by the one it doesn't.

Notice what is not here: we did not force every tool into a chain. Plenty of these gifts are perfectly good alone — a CSS-color check, a Sudoku solver, an ID mint. Composition is a thing you reach for when the shapes line up, not a tax every tool has to pay. Teach it where it lives.

Proving a chain before you run it

Two tools snapping together is easy to eyeball. Six or ten is not — and a long pipeline that fails on the last stage has already wasted the first nine. So this system ships the tools that let you prove a chain is sound before you run a single command. They are gifts like any other: one file, zero dependencies, an honest edge.

They share one deep, honest boundary, and understanding it is the whole point of this section: they prove the TYPE layer — that the pipes can carry data at all — and they refuse to claim the RECORD layer, the question of whether the data one tool hands over is the data the next one actually expects. Everything below either proves the type layer or is honest that it can't reach the record layer. That line is not a weakness; it is the seam where your own work begins (see the next section).

The toolchain, in the order you reach for it

  • portdeclare what a tool is. Every composable tool names its role (source, filter, transform, fold, sink) in one place. port checks that a tool's declaration is consistent with itself — the manifest field against the tool's own --port flag. Its edge: it proves the declaration agrees with itself, not that the declared verb is true of the code. A tool can honestly say "filter" in both places and still behave like a transform; proving a verb against real behavior is a deeper, generally-undecidable question port does not claim to answer.
  • typecheckcan these two snap together at all? Given two stages, it validates that the port types line up so data can flow. Its edge: it validates the PORT type, not the RECORD shape. Two tools can both speak JSON-lines — so the ports agree — while the records one emits are not the records the other expects. That pipeline typechecks clean here and still fails at runtime. typecheck flags the record-shape layer as unproven and never asserts it.
  • mapsee the whole chain at once. Where typecheck is pairwise, map renders the type-level map of an entire pipeline, so you can spot where the ports stop agreeing across ten stages. Its edge, identical in spirit: it renders the TYPE-level map — whether the ports agree — not whether the records fit. A transform emitting {event} records maps clean into a filter expecting {file} records and then fails at runtime; map flags that semantic layer as unproven and never asserts it.
  • declarewrite the pipeline down. Once a chain is one you trust, declare saves it as a named score you can re-run and hand to someone else. Its edge: it SAVES a pipeline; it does not validate it (that's typecheck) and does not run it. It will faithfully record a score that would not typecheck — it claims only that the pipeline is written down, never that it is runnable. With --manifest it flags any stage that isn't a declared tool, saving the score anyway and flagging it, never silently dropping a stage.
  • conductorrun the score, with a receipt. conductor executes a declared pipeline in order and leaves a provenance receipt of what ran. Its edge, and read it before you trust a run: conductor runs the commands you give it — it is exactly as safe as those commands, and it does not sandbox them. Its built-in typecheck is the type-level gate (ports line up), not a proof the records fit or that a stage is correct. It proves the run happened, in order, with a receipt; it never proves the run was right.

Put them together and the shape is: port (each tool is honestly labelled) → typecheck / map (the labels line up across the chain) → declare (write the trusted chain down) → conductor (run it, keep the receipt). At the end you have a pipeline that is proven to carry data and proven to have run in order — and that is honestly not the same as proven correct. What the toolchain hands you is a chain whose plumbing is sound. Whether the meaning flowing through it is right is the layer you own — which is the next section.

The glue layer you build

Here is the thing no honest guide to composition can leave out: the interesting compositions are never just tools in a line. Between the tools there is a layer you write yourself — the policy, the merge rule, the small harness that decides what happens where two honest tools meet and their edges leave a gap. The tools are the ingredients. The glue is the recipe, and the recipe is yours.

You already saw exactly where the glue lives: the provability toolchain proves the type layer and hands you the record layer. That handed-over layer is glue. When a transform emits {event} records and the next filter wants {file} records, no gift bridges that for you — you write the small adapter that maps one record shape to the other, and you are the one asserting the semantics are right. The type-check told you a gap existed; closing it honestly is your work.

The glue shows up in three recurring shapes, and naming them means you'll expect them instead of being ambushed by them:

  • A merge policy — when two branches of a pipeline fan out and have to come back together, you decide the rule for combining them. Two tools can each produce a valid stream; the decision about how they reconcile — last-wins, union, first-non-empty, a real merge — is a policy the tools do not carry. It is a choice, so it is yours to make and state plainly.
  • A boundary check — where a chain crosses from "data I trust" to "data from outside," you add the assertion the tools don't. A gift filters or folds what it's given; whether what it's given is safe to act on is a boundary you draw. The ambitious Reddit-style compositions are mostly this: a spine of honest tools with a guard you wrote at each place the data changes hands.
  • A harness — the loop, the retry, the "call this N times and collect the answers" scaffold that turns single-shot tools into a batch. A fan-out to many calls and a fold back to one is a real pattern (it is how the model-calling pipelines are built), but the N, the collecting, and the what-if-one-fails are harness code you own around the gifts.

This is not a gap in the tools — it is the design working as intended. A gift that tried to be honest about its own edge and guess your merge policy and hold your trust boundary would be a framework, and a framework is the opposite of a gift. The tools stay small and honest precisely so that the judgment — the part that is actually about your problem — stays with you. Compose the plumbing from what ships; write the meaning yourself. That division is the whole method.

These are yours

Everything here is free, MIT-licensed, and runs with what its Stack line already names — no account, no telemetry, no dependency you did not ask for. Take one. Take the pair. Take all of them. Read the edge before you lean on a tool, and it will never surprise you.

If you want to know how these were made and why they compose the way they do, there is more underneath — but you never need it to use the tools. The tools come first. The story is optional, and it is down the page, not in your way.

Part two — building your own

Once you can compose, you can contribute. A gift is the smallest thing this system ships: one file, zero dependencies, MIT. Here is how to build one so every honesty property is a checked fact, not a promise.

What a gift is

A gift is the smallest thing Loop MMT ships to the world: a single file, zero dependencies, MIT-licensed, that runs both as a command-line tool and as a browser-attachable pure function. It does one job, states plainly what it does not do, and asks nothing of you — no account, no install, no server. You copy the file and it works.

That severe shape is not a limitation we tolerate; it is the point. A gift is honest by construction: there is nowhere for a hidden dependency, a phone-home, or an unstated assumption to live. This guide is how you build one our way — through a path that makes every one of those honesty properties a checked fact rather than a promise.

This is the builder's guide. If you want to use the gifts to compose something, the Gifts Users Guide teaches that. This one teaches how to make a new gift and bring it into the cabinet.

The covenant — the four things that make a gift a gift

Before any procedure, hold the covenant. These four properties define a gift; break any one and what you have is a tool, not a gift. Each is a loud stop, not a warning to absorb — the path refuses at the covenant, at the gate, deliberately.

  • MIT licensed. Anything else is a loud stop. A gift is given away.
  • Zero dependencies. No npm, no imports, no runtime you don't ship. A single file that stands alone.
  • Two homes, byte-identical. A gift lives in two places: its design home (the private tree where it is authored) and the served tree (<served>/gifts/<slug>/, the public copy). The two must be byte-for-byte the same — a decidable cmp, not a hope.
  • A printed edge. One sentence, shipped in the file, stating what the gift does not do — so a caller cannot misuse it. sha256's edge: a hash, not encryption, not a password KDF — it proves two inputs match, it keeps no secret.

The path — five moves, in order

You build a gift by walking The Gift-Works Procedure: five moves forward, plus a strip that precedes them and a landing that closes them. The moves are ordered. A missing or stale predecessor is a loud stop, never a fast path. Each move ends in a decidable byte-oracle — a cmp, a byte-equal trace, a hash — so a deviation is caught at its step, not discovered at ship.

  1. Step 0 — The strip. A gift usually already exists as code inside a larger tool. You strip it out: extract the pure function, cut everything that tied it to its old home, and record what tool it came from and what you cut. That provenance is the gift's most valuable decision. Read the stripped code first — the one-line description is a lead, not a spec (this line mis-scoped a candidate three times by trusting the gloss).
  2. Step 1 — The Blueprint. Author the gift's canonical Blueprint against the Gift Blueprint Profile. The Blueprint is the product; the code is the artifact. It states what the gift is: its identity, its in-type → out-type signature and the fidelity rule that binds them (this is the single most load-bearing line — sha256's is String → 64-char lowercase hex, hashing UTF-8 bytes, never char codes), its two surfaces (CLI and browser attach), and the covenant's four fields as declared facts. Register it, or it does not exist.
  3. Step 2 — The Plumb. Bless what perfect looks like: a reference build, a golden input/output corpus, and the invariant contract. The golden corpus draws its known-bad half from real defects — the bug that actually bit once becomes the tripwire — never from author-invented failures. The canonicalizer's self-test is the gift's own determinism check: run it under many seeds, assert the output is byte-identical every time. For a gift, that is the proof it is a pure function.
  4. Step 3 — The Agent File. Render the gift's AGENTS.md from the Blueprint plus the gift config. It homes in the gift's own design tree, alongside the gift file — a gift binds no constellation, so its design tree is its project. Every place the gift bends from the default maps to a declared config point, or it is a loud stop.
  5. Step 4 — Conformance. Run the out-of-band checker: replay the Plumb's blessed scenario, apply the one canonicalizer to both sides, and byte-compare the traces. Emit a signed, version-pinned conformance record. Non-conformance is no ship, loudly. This is the load-bearing addition — shipped means the trace conforms to the Plumb, not merely that the tests pass.
  6. Step 5 — Acceptance & landing. Run the Self-Review Pull against live bytes, examine the finished gift for one genuine improvement to promote back into the Blueprint (so the next gift renders from a warmer path), then land it through the close. Every ship gate the line already runs stays; conformance is the new one.

The loopback — why every gift makes the next one easier

The fifth move carries the part that makes this a system rather than a conveyor belt. When a gift is finished, you look back at it and ask: did building this teach me something the Blueprint should know? A sharper invariant, a better edge sentence, a stronger canonicalizer, a reusable shape. If it is genuine, you promote it — an atomic write back into the Blueprint and Plumb that render the next gift.

So the path is not run-once. It is run → formalize → run → sharpen. The first gift (sha256) was walked cold, then this procedure was written from the doing. Every gift since renders from a warmer Blueprint than the last. That is the loop worth building for.

A worked example — sha256, end to end

The cleanest first pass through the whole cycle was sha256: browser-synchronous SHA-256, hex out. Small, pure, decidable from bytes, with obvious golden vectors and a canonical form that is the output (the hash is its own canonical form). Here is the trail, so you can see the five moves as real acts, not abstractions:

  1. Strip: extracted from an internal shell tool to the served tree — already shipped, but with no canonical tier (no Blueprint, absent from the registry).
  2. Blueprint: authored against the gift profile; a design→canonical flip for an already-existing artifact, with the strip recorded as its first provenance entry.
  3. Plumb: golden vectors from Node's own crypto library (the out-of-band oracle) plus a multibyte known-bad vector — the tripwire for the char-code bug that bites naive SHA-256 implementations. The determinism lint is the canonicalizer self-test.
  4. Conformance: the out-of-band checker plus a signed, version-pinned record (trace vs Plumb, canonicalizer version, seed set).
  5. Acceptance: rendered the Agent File in the design home, ran the Pull in place (every claim re-verified against live bytes), found one real over-generalization and routed it to the operator, then landed — with the two homes held byte-identical by the cmp gate.

The loud stops — where the path refuses

A gift's path refuses, loudly, at any of these. None is a warning to route around; each is a stop to surface — because a gift that bends here is not a gift.

  • a non-MIT license, or any dependency (the covenant);
  • a stale or missing Blueprint or Plumb at the gate;
  • a byte difference between the two homes;
  • a missing printed edge, or a Blueprint edge that disagrees with the shipped edge;
  • non-conformance to the Plumb;
  • a multi-file format — a gift is single-file by definition.

Building in a wave — when gifts arrive together

The path above builds one gift. But gifts rarely arrive one at a time — they come in waves: a batch commissioned together, built in parallel, landing over hours or days. A wave changes nothing about the covenant or the five moves — each gift still walks the whole path and passes every gate alone. What a wave adds is three relationships between gifts, and each is a loud stop of its own.

Declare the port-verb — how a gift joins a pipeline

Every gift declares one port-verb in its Blueprint — source, transform, filter, fold, or sink — the single word that says how it composes. This is not decoration: it is what lets a pipeline be proven valid before it runs. Build the verb in from the Blueprint, not bolted on after. A gift with no declared verb is a gift no one can safely snap onto another — it fails the composition contract even when it passes its own tests. (How a user reads these verbs to compose a pipeline is the Gifts Users Guide's job; your job as builder is to declare the verb honestly, so the user's type-check tells the truth.)

The pair-braid — when two gifts are one unit

Sometimes two gifts are commissioned as a pair that only makes sense together — one splits, its partner rejoins; one opens, its partner closes. When that happens, neither ships until the pair round-trips. The worked instance is fanout (the ⊗-open: split one input into a declared, closed set of named branches) paired with junction (the ⊗-close: fold those branches back under a declared merge policy). Fanout is not done when fanout's own tests pass — it is done when a fanout → junction braid round-trips byte-identically under a declared merge policy. The braid is the acceptance test; the two Blueprints share it. Build a pair by building the braid, not two gifts that happen to be adjacent.

Binding dependencies — when one gift needs another

A gift may be bound to another by construction: it cannot ship without its dependency present and honest. When that binding exists, it is a covenant field, not a nicety — the path refuses if the dependency is absent. In the current wave, seance (channel a deleted prompt from git history) is Scrub-bound: it must route its recovered text through scrub before it surfaces, or it does not ship — recovering a secret someone deleted on purpose is the exact harm the binding prevents. Declare the binding in the Blueprint, gate on it at conformance, and treat a missing dependency as a loud stop.

What "landing" means while you wait

In a wave, the cabinet below will show some siblings as landing — named, commissioned, not yet in served bytes. That is not an error; it is the honest state of a gift still in flight. Three from the current prompt-gift wave are landing as this is written: scrub (strip declared-shape secrets from a prompt before paste — shapes, not semantics), contract (assert a model's JSONL output matches a declared record schema at runtime — reject the first bad record, name the field), and seance (above, Scrub-bound). When each lands in served bytes, the cabinet folds it from landing to shipped on its own — the appendix is derived from The Tally, not hand-edited. A builder joining the wave reads the cabinet to see which siblings are still open, and builds theirs to the same path.

The cabinet you're adding to

Every gift already in the collection, folded live from the manifest and The Tally — the same oracle the crown reads, so this table cannot drift from the truth. Your new gift joins this shelf; build it to the same covenant.

giftmaturity
amber ambershipped + forge-hardenedsee it →
cairn Cairnshippedsee it →
callsigns Callsignsshippedsee it →
census Censusshippedsee it →
clause-trellis Clause-Trellisshipped + forge-hardenedsee it →
conductor conductorshipped + forge-hardenedsee it →
confessional Your Prompt Goes to Confessionshipped + forge-hardenedsee it →
conflict Conflictshippedsee it →
cruise Cruiseshippedsee it →
declare declareshippedsee it →
derived derivedshipped + forge-hardenedsee it →
doppelganger Your Prompt's Evil Twinshipped + forge-hardenedsee it →
dwell Dwellshippedsee it →
excavation The Excavationshippedsee it →
exif-parser EXIF Parsershippedsee it →
fanout Branch Splittershipped + forge-hardenedsee it →
forest-title-fit forest-title-fitshippedsee it →
gauntlet gauntletshipped + forge-hardenedsee it →
gitlog Gitlogshippedsee it →
grain Grainshippedsee it →
hunkhole Hunkholeshippedsee it →
isvalidcsscolor Isvalidcsscolorshippedsee it →
jsonl-diff JSONL-Diffshipped + forge-hardenedsee it →
junction Branch Mergershipped + forge-hardenedsee it →
l21x-snapshot l21x-snapshotshippedsee it →
legible Text Legibility Gaugeshipped + forge-hardenedsee it →
loop21-component-factory loop21:component-factoryshippedsee it →
loop21-l21x-snapshot loop21:l21x-snapshotshippedsee it →
loop21-verifyskin Skin Config Validatorshippedsee it →
map mapshippedsee it →
markdown Markdownshippedsee it →
mint Mintshippedsee it →
palimpsest Palimpsestshipped + forge-hardenedsee it →
parity Parityshippedsee it →
plumb Plumbshippedsee it →
port portshipped + forge-hardenedsee it →
quorum Ask Three, Trust The Overlapshipped + forge-hardenedsee it →
ratchet-inline-mime Inline MIME Parsershippedsee it →
ratchet-pdf-dict PDF Dictionary-Text Extractorshippedsee it →
ratchet-pdf-text PDF Text Extractorshippedsee it →
ratchet-png-text PNG Textshippedsee it →
reading-oath Make The AI Prove It Read The Whole Thingshipped + forge-hardenedsee it →
reltime Reltimeshippedsee it →
scrub Scrubshipped + forge-hardenedsee it →
sha256 Sha256shipped + forge-hardenedsee it →
sudoku Sudokushippedsee it →
switchboard switchboardshipped + forge-hardenedsee it →
template The Mail-Merge That Won't Lieshipped + forge-hardenedsee it →
the-oracle The Oracleshipped + forge-hardenedsee it →
timeline timelineshipped + forge-hardenedsee it →
timesheet Timesheetshipped + forge-hardenedsee it →
tracebus Tracebusshippedsee it →
trellis The Trellisshippedsee it →
typecheck typecheckshipped + forge-hardenedsee it →
vclock Vclockshippedsee it →
verify Verifyshippedsee it →
ward Wardshippedsee it →
weir weirshipped + forge-hardenedsee it →
worklog Worklogshippedsee it →