MEMEROOT · ARCHITECTURE · CANONICAL REFERENCE · 2026-002
Composable XML with strict block separation.
Every Memeroot artifact decomposes into one of six fundamental block kinds — schema, script, template, data, process, projection — with zero crossover between kinds. Each kind has its own XML namespace, its own root element, its own projection XSL. The TABLE_SPECIFICATIONS spine is the only place block kinds meet, and they meet only as projections, never as inclusions. The result is completely addressable combinatory space.
Section 01The thesis
Every system worth building eventually faces the same question: how do you keep structure separate from content, schema separate from data, process separate from script, while still composing them into something a user can address with a single query? Most systems fail this test the moment they try to scale past a single team's mental model.
The Memeroot composable XML architecture takes a position that is older than the systems it competes with: structure goes in one block, content in another, never the same file. Then projects them through a universal lens (TABLE_SPECIFICATIONS) into a single addressable surface where any query against any block kind returns rows in the same canonical shape.
The pattern is not new. It is the same pattern that the MBI_SCRIPT framework has used in production for a decade, that Bach used to organise the Well-Tempered Clavier, that ISO 8601 uses to address time, that Codd's relational model uses to address data. What is new in this iteration is that the framework is specified as composable XML blocks with explicit projection stylesheets, so it can be implemented in any database, any file system, any in-memory engine, against any storage substrate, without rewriting any of the model itself.
The thesis in one sentence: separation in storage, unification in projection.
Section 02Five axioms of the substrate
The architectural decisions in this document follow from five non-negotiable axioms. They are restated from MEMEROOT-REF-2026-001 (the Oracle Free Framework specification) because they are the load-bearing constraints. Every block kind, every projection, every composition rule respects all five.
- Axiom I · Purity of resolution
- Every value resolves to exactly one canonical byte sequence. No whitespace tolerance, no attribute-order tolerance. A value matches a hash exactly or it does not.
- Axiom II · Byte-stability
- Parse then serialise must reproduce the same bytes. If a roundtrip changes one byte, signatures break, hashes break, the audit trail breaks. XSL projections are byte-stable transforms; the spine is byte-stable; the unit composition is byte-stable.
- Axiom III · Null-strict canonicalisation
- No fuzzy matching, no cosine similarity, no “close enough”. A spine row matches an address exactly or it does not. The spine has no probabilistic membership.
- Axiom IV · Content addressing
- The address of a cell is the cell's identity. Move a block from one file system to another; the addresses of its rows do not change. The spine is the universe of addresses; the blocks are projections into it.
- Axiom V · Total provenance
- Every spine row carries
spec-source identifying the block kind that produced it. Anonymous content can exist, but it is marked as such; it cannot pose as attested. Where a block carries a cryptographic signature, the signature transits with the projection.
Section 03The block kinds
Six fundamental block kinds. Each has its own XML root element, its own namespace, its own file extension convention, and its own projection XSL. No block kind contains any element of another block kind; cross-references are by address only.
schema-block · *.schema.xml · ns http://memeroot.io/block/schema/v1
The shape of data, without data.
- Declares tables, columns, types, indexes, constraints, view definitions
- Holds NO values, NO scripts, NO templates
- Address-scoped:
OWNER.NAME.PREFIX
- Example:
ts-TABLE_SPECIFICATIONS.schema.xml declaring the 21 columns of the spine itself
script-block · *.script.xml · ns http://memeroot.io/block/script/v1
Executable source, in its native language.
- Holds PL/SQL, KSH, JS, Python, Bash, SQL — any executable text
- Source in CDATA. Inputs declared as typed parameters. Outputs declared as typed streams or artifacts
- Holds NO data values, NO schema declarations, NO templates
- Example:
sc-pmexecutequery.script.xml wrapping Rob's 2017 pmrep CLI wrapper
template-block · *.template.xml · ns http://memeroot.io/block/template/v1
Generation patterns with token placeholders, awaiting binding.
- Lines of template text with
<<TOKEN>> placeholders
- Loop flags, indent levels, condition tokens — direct mapping to MBI_SCRIPT row structure
- Holds NO data values, NO schema declarations, NO executable scripts
- Example:
tp-CREATE_TABLE.template.xml with four template lines that generate any DDL CREATE TABLE statement
data-block · *.data.xml · ns http://memeroot.io/block/data/v1
Pure values. Rows. Cells. No code, no shape.
- Rows of typed cells, referencing their schema by address (
schema-ref address="...")
- Holds NO schema declarations inline, NO executable scripts, NO templates
- Example:
dt-MBI_SCRIPT-rows-CREATE_TABLE.data.xml — four rows of MBI_SCRIPT that contain the CREATE_TABLE template lines as data
process-block · *.process.xml · ns http://memeroot.io/block/process/v1
Orchestration sequences — addresses only, never bodies.
- Steps. Each step
invokes a block kind at an address
- Holds NO script bodies inline, NO data values, NO templates — only references by address
- Example:
pr-bounded-dispatch.process.xml — the four-step bounded-execution dispatch pattern from §8 of MEMEROOT-REF-2026-001
projection-block · *.xsl · the universal lens kind
XSL stylesheets that project from one block kind into the spine.
- Pure transformations. Total. Deterministic. Byte-stable.
- One projection XSL per block kind
- Holds NO domain content, NO business logic — only the transform from kind X to
<table-spec> rows
- Examples:
schema-to-spine.xsl, script-to-spine.xsl, template-to-spine.xsl, data-to-spine.xsl, process-to-spine.xsl
Future block kinds
Two more block kinds are declared but not yet implemented in this turn: address-block (pure address declarations with no payload) and binding-block (resolves spine addresses to concrete physical sources — Oracle table, MinIO object, file path, REST endpoint). These complete the model. The projection pattern for each is structurally identical to the six above.
Section 04Strict separation rule
The architecture only works if separation is strict. The moment a script-block contains an inline data row, or a data-block embeds a template token, the projection becomes ambiguous and the addressable space leaks. This section states the rule plainly and the consequences of violating it.
The rule
A block of any kind MUST NOT contain elements of another block kind. Period. The XSD or RNG schema for each block kind disallows the namespaces of all other block kinds at every level. The validator rejects cross-kind inclusion with a hard error.
Cross-references between blocks use the address attribute pattern: <schema-ref address="OWNER.NAME"/>, <invokes kind="script-block" address="OWNER.NAME"/>. The reference is a coordinate; the target is resolved at composition time by querying the spine.
Why this matters
- Composability
- A schema-block can be authored by a database architect, a script-block by a developer, a template-block by a code-generation specialist, a data-block by an analyst, a process-block by an orchestration engineer — independently, in different repositories, in different versions, with different signatures. The compose-unit step reads them all and produces the unified spine. Composability comes from the discipline, not from a magic tool.
- Addressability
- Every cell in the universe has exactly one address. The address is
(target-owner, target-name, target-attribute, target-id?). Multiple block kinds can project rows at the same address, but each projection carries its spec-source so the consumer knows which lens to use. No collision; no overwriting; preservation of all views.
- Substitutability
- Want to swap MBI_SCRIPT's CREATE_TABLE template for a different generation engine's DDL pattern? Replace the template-block, recompose. The schema-block doesn't change. The data-block doesn't change. The process-block doesn't change. Each block is interchangeable because nothing depends on another's internal structure.
- Auditability
- Every spine row carries
spec-source and (when signed) the publisher fingerprint. An auditor querying the spine for “everything signed by Memeroot Founder targeting OWNER_FIN” gets an answer in one query. The audit trail is the spine.
What violation looks like
Mixing kinds creates implicit dependencies. A data-block that embeds a script becomes a hybrid that can't be projected by either the data XSL or the script XSL alone. A schema-block that contains inline data values mixes the “shape of the universe” with “specific points in the universe”; queries that want one and not the other become hard to write. The discipline is the architecture. Loosen the discipline and the architecture isn't there any more.
Section 05The spine · TABLE_SPECIFICATIONS as projector
The TABLE_SPECIFICATIONS spine is not a physical table. It is a view of views that absorbs projections from any addressable source and presents them as a unified set of <table-spec> rows. Each row is positioned in the universal address space by its target-* coordinates. Each row carries its provenance in spec-source. The spine is the only place block kinds meet.
The row shape
<table-spec spec-source="schema-block | script-block | template-block | ...">
<source owner="..." name="..." attribute="..." datatype="..."/> // origin coordinates
<target owner="..." name="..." prefix="..." attribute="..."
datatype="..." nullable="N|Y" default="..." id="...">
<function><![CDATA[ ... ]]></function> // the payload (column def, template line, script body, data value)
</target>
<index type="pk|fk|uk|idx"/> // optional index marker
<constraint filter-flag="L|S|i|d|p" condition="" join-condition=""/>
<view owner="" filter="" prefix=""/> // which view this row participates in
<ext> // block-kind-specific extensions
<field name="block-id">...</field>
<field name="category">...</field>
<field name="is-loop">...</field>
<field name="condition-token">...</field>
</ext>
</table-spec>
The filter flags
| Flag | Meaning | Emitted by |
i | Identity column — part of the spine's PK / shape | schema-block projection |
S | Single — template line that emits once | template-block projection (non-loop) |
L | Loop — template line that iterates | template-block projection (loop) |
d | Data — value cell from a data-block | data-block projection |
p | Process step — orchestration invocation | process-block projection |
What the spine absorbs
Any source that can be projected into the <table-spec> row shape can join the spine. The five block kinds above are the canonical sources; others can be added by writing a projection XSL. Concrete near-term candidates: Oracle ALL_TAB_COLUMNS data dictionary, Informatica metadata exports, Documentum object models, REST API specifications (OpenAPI), graph schema definitions, ontology declarations. Each becomes a projection-block emitting <table-spec> rows. Once they project, they federate.
Section 06Projections · XSL as the universal lens
XSL is the substrate's transformation language. Every block kind ships with a projection XSL that transforms its native form into spine rows. The XSL is pure, total, deterministic, byte-stable. The same XSL works in any XSLT 1.0 processor — libxslt (xsltproc), Saxon, browser XSLTProcessor — making the projection portable to any environment.
The five projection stylesheets
| XSL | Input | Output | Rows per input |
schema-to-spine.xsl | schema-block | spine rows, one per <column> | N (per table column) |
script-to-spine.xsl | script-block | spine row for body + one per parameter | 1 + N (params) |
template-to-spine.xsl | template-block | spine rows, one per <line> | N (per template line) |
data-to-spine.xsl | data-block | spine rows, one per <cell> | rows × cells |
process-to-spine.xsl | process-block | spine rows, one per <step>'s <invokes> | N (per invocation) |
The MBI_SCRIPT pattern as direct ancestor
The template-to-spine XSL is the XML analogue of MBI_SCRIPT_AS_TABLE_SPEC_V, the production view that has run in Rob Anderson's enterprise deployments for the past decade. The SQL view emits two row types per template line:
- A HC (Hard Coded) row that places the template-line text as
target_function at address OWNER_MBI.MBI_SCRIPT.SCRIPT_TEXT with the script's category/object-type/script-name/sequence as extension columns
- A source mapping row that places the MBI_SCRIPT column metadata (the column itself is in the schema) at the same target
In the XML architecture, those become two separate projections: the template-to-spine XSL emits the HC rows; the schema-to-spine XSL emits the source-mapping rows. Strict separation in storage; same address in projection; both visible in the spine. The SQL pattern's UNION ALL becomes the XML pattern's compose-unit.sh — different syntax, identical semantics.
Section 07The self-referencing graph
The most interesting property of the spine is that the spine describes itself. The schema-block ts-TABLE_SPECIFICATIONS declares the columns of TABLE_SPECIFICATIONS. Projecting that schema-block through the schema-to-spine XSL produces a set of spine rows that describe the spine's own columns. The spine is a fixed point of its own projection.
This is not a curiosity. It is the property that makes the architecture extensible without leaving the architecture. Add a new column to the spine? Write a new schema-block, project it, the spine grows. Add a new view over the spine? Write a projection-block, register it, the spine has a new lens. Add a new block kind entirely? Define its namespace, write its projection XSL, every other block kind keeps working unchanged.
Multiple views at the same address
The same target address — OWNER_MBI.MBI_SCRIPT.SCRIPT_TEXT — appears in the composed spine from three different block kinds:
- schema-block view
- One row. spec-source="schema-block". The row declares what SCRIPT_TEXT is: column 5 of MBI_SCRIPT,
VARCHAR2(4000), NOT NULL. This is the abstract definition.
- template-block view
- Seven rows. spec-source="template-block". Each row carries one template-line value in
<function>, with the template's category/object-type/script-name/sequence in ext. These are specific values that SCRIPT_TEXT holds, projected from the template-block's structured view of those values.
- data-block view
- Four rows of data-block-sourced cells. spec-source="data-block". Each carries one cell value with
<function> as the raw value. The same content as the template-block view, projected from a different block-kind perspective.
The consumer chooses which lens to query through. A code generator looks at the template-block rows (sees the structured template metadata). A data analyst looks at the data-block rows (sees raw cells). A data architect looks at the schema-block row (sees the column definition). All three are valid; all three are present; none overrides another.
Views on views
The spine is itself a view (the UNION ALL of all projections). Additional views can be defined on the spine, in pure XSL, that filter, group, or join spine rows for specific purposes. A “templates-only” view filters for spec-source="template-block". A “control-coverage” view joins schema-block rows to data-block rows by target address. A “dispatch-trace” view filters for spec-source="process-block" and orders by step-seq.
Each derived view is its own projection-block XSL. Views can be views on views. The graph is acyclic in dependency (no projection depends on its own output) but expressive in topology (any DAG of projections is valid).
Section 08Worked example · eight blocks → 77 spine rows
The shipped delivery includes a worked compose: eight blocks across five kinds, drawn from real artifacts in Rob Anderson's 25-year practice (TABLE_SPECIFICATIONS, MBI_SCRIPT, pmexecutequery.ksh, the AFFIRM GEN_LPV_TRANS_FEAT pattern). One compose-unit.sh invocation produces a 77-row spine plus an HTML rendering. Reproduce locally with bash projections/compose-unit.sh.
The eight input blocks
| Kind | Block id | Source |
| schema-block | ts-TABLE_SPECIFICATIONS | The spine describing itself |
| schema-block | ts-MBI_SCRIPT | The MBI_SCRIPT template-storage table |
| script-block | sc-pmexecutequery | Rob's 2017 pmrep CLI wrapper |
| script-block | sc-exe_var_deletefolder | Minimal POSIX delete-folder helper |
| template-block | tp-CREATE_TABLE | Four-line DDL CREATE TABLE template |
| template-block | tp-GEN_LPV_TRANS_FEAT | Translation-view generator from AFFIRM spec |
| data-block | dt-MBI_SCRIPT-rows-CREATE_TABLE | Four MBI_SCRIPT rows storing CREATE_TABLE |
| process-block | pr-bounded-dispatch | The four-step bounded-execution pattern |
The composed spine
| spec-source | rows | What it represents |
schema-block | 30 | 21 spine columns + 9 MBI_SCRIPT columns |
template-block | 7 | 4 CREATE_TABLE lines + 3 GEN_LPV_TRANS_FEAT lines |
script-block | 5 | 2 script bodies + 3 input parameters |
data-block | 30 | 4 rows × ~7 cells each |
process-block | 5 | 4 dispatch steps + extra invocation |
| TOTAL | 77 | One unified addressable view |
A sample query against the composed spine
# “Show me every projection that targets MBI_SCRIPT.SCRIPT_TEXT”
xmllint --xpath "//table-spec[target/@name='MBI_SCRIPT' and target/@attribute='SCRIPT_TEXT']" spine.xml
# Returns 12 rows:
# - 1 schema-block row defining SCRIPT_TEXT as VARCHAR2(4000) NOT NULL (column #5)
# - 7 template-block rows (4 from CREATE_TABLE, 3 from GEN_LPV_TRANS_FEAT)
# - 4 data-block rows (the SCRIPT_TEXT values of the CREATE_TABLE data rows)
#
# All twelve preserved. Consumer chooses spec-source to filter.
Section 09Composition into the unit · the zip
A composed unit is a zip. Inside: a manifest of every block, the canonical projection stylesheets, the spine output, and a build script that reproduces the spine from the inputs. Open the zip on any machine with libxslt installed; run bash projections/compose-unit.sh; the spine recomposes byte-identically.
Unit zip structure
memeroot-composable-xml/
├── README.md # quickstart
├── ARCHITECTURE.html # this document
├── manifest.json # list of every block + its hash + signature
│
├── schemas/
│ └── spine.schema.xml # the universal projection target
│
├── blocks/
│ ├── schema/
│ │ ├── ts-TABLE_SPECIFICATIONS.schema.xml
│ │ └── ts-MBI_SCRIPT.schema.xml
│ ├── script/
│ │ ├── sc-pmexecutequery.script.xml
│ │ └── sc-exe_var_deletefolder.script.xml
│ ├── template/
│ │ ├── tp-CREATE_TABLE.template.xml
│ │ └── tp-GEN_LPV_TRANS_FEAT.template.xml
│ ├── data/
│ │ └── dt-MBI_SCRIPT-rows-CREATE_TABLE.data.xml
│ └── process/
│ └── pr-bounded-dispatch.process.xml
│
├── projections/ # pure XSL; no domain content
│ ├── schema-to-spine.xsl
│ ├── script-to-spine.xsl
│ ├── template-to-spine.xsl
│ ├── data-to-spine.xsl
│ ├── process-to-spine.xsl
│ ├── spine-to-html.xsl # render unified spine in Memeroot style
│ └── compose-unit.sh # orchestrates the projections
│
└── examples/
├── spine.xml # the composed spine (77 rows)
└── spine.html # human-readable view
Reproducibility
Every consumer of the zip can recompose the spine independently. The inputs are byte-stable. The XSL is byte-stable. xsltproc is deterministic. bash compose-unit.sh emits the same bytes from the same inputs. Verification is a hash comparison: re-run, hash, compare to the publisher's signature.
MMP and set-independent dispatch
Each block in the unit can be projected independently. The unit doesn't need to compose the entire spine to use any one piece. A massively-parallel-processing layer reads the manifest, dispatches per-block projections to independent worker processes, collects the resulting <table-spec> streams, and merges them into the spine — or routes them to whatever execution substrate makes sense for that block kind. Set independence in dispatch follows from the strict separation in storage.
Section 10What was built · file inventory
This delivery ships fourteen working files: spine schema, eight blocks across five kinds, six projection stylesheets, one compose driver, one ARCHITECTURE document, plus the composed outputs as XML and HTML. Each file is concretely usable. The compose script runs and produces the 77-row spine in 0.1 seconds with no dependencies beyond xsltproc.
Spine schema (1)
schemas/spine.schema.xml — the universal projection target shape with row-form documentation, projection rule, composition rule, strict-separation rule
Blocks (8)
blocks/schema/ts-TABLE_SPECIFICATIONS.schema.xml — 21 columns of the spine itself
blocks/schema/ts-MBI_SCRIPT.schema.xml — 9 columns of the template-storage table
blocks/script/sc-pmexecutequery.script.xml — Rob's 2017 Informatica wrapper, with typed inputs and env-required declarations
blocks/script/sc-exe_var_deletefolder.script.xml — minimal POSIX delete helper
blocks/template/tp-CREATE_TABLE.template.xml — 4 template lines with loop, condition tokens, indent levels
blocks/template/tp-GEN_LPV_TRANS_FEAT.template.xml — translation-view generator from the AFFIRM spec
blocks/data/dt-MBI_SCRIPT-rows-CREATE_TABLE.data.xml — 4 MBI_SCRIPT rows storing CREATE_TABLE as data
blocks/process/pr-bounded-dispatch.process.xml — 4-step bounded-execution dispatch pattern referencing schema, template, script, audit blocks by address
Projections (6)
projections/schema-to-spine.xsl — schema-block → spine rows (one per column)
projections/script-to-spine.xsl — script-block → spine row for body + one per parameter
projections/template-to-spine.xsl — template-block → spine row per line, replicating MBI_SCRIPT_AS_TABLE_SPEC_V Row Type 1 semantics
projections/data-to-spine.xsl — data-block → spine row per cell
projections/process-to-spine.xsl — process-block → spine row per step invocation
projections/spine-to-html.xsl — composed spine → Memeroot-styled HTML view with per-kind counts, colour-coded spec-source pills, sortable
Driver (1)
projections/compose-unit.sh — walks blocks/, routes each file to the right projection by directory, emits <spine> UNION ALL output, generates the HTML view
Reference outputs
examples/spine.xml — 44 KB, 77 spine rows from the eight input blocks
examples/spine.html — 63 KB, human-readable Memeroot-styled view of the same data
Section 11Integration with the existing Memeroot stack
The composable XML architecture is the structural discipline beneath everything previously built in the Memeroot stack — canvas, CLI, skill packs, demo packets, catalog. None of those need to change; they become specific block-kind shapes wearing the existing region-XML clothing.
How existing region kinds map
| Existing region kind | Underlying block kind(s) |
<control> (SOX REV-001) | process-block (the control as a process) + schema-block (the control structure) |
<test-of-design> | process-block (the test sequence) |
<test-of-operating-effectiveness> | process-block + data-block (the sample results) |
<iframe-region> | data-block (the snapshot CDATA is data) |
<svg-region> | data-block (the SVG content is data) |
<note>, <decision>, <task>, <reference> | data-block (each is a typed value record) |
<workspace> | process-block (the workspace is an orchestration container) |
<skill> | composition of schema (parameters) + script (helper scripts) + template (output templates) + process (workflow) |
What this enables
- Cross-region queries via the spine. “Show me every signed audit packet that contains a captured-hash iframe-region from a publisher whose fingerprint matches X” — one XPath against a composed spine.
- Skill packs become composable from blocks. A new skill pack is: one or more schema-blocks (input shape), one or more template-blocks (output templates), one or more script-blocks (helpers), one process-block (workflow). Authoring a skill is composing blocks, not editing monolithic XML.
- Catalog publishers' federation becomes addressable. Each publisher's signed entries are blocks in their own zip; the catalog curator's manifest is a process-block referencing them by address; the spine projection shows the federation as data.
What does NOT change
None of the existing deliverables in the previous 22-entry catalog need to be reauthored. The composable XML architecture is a refinement of how new content is structured going forward, not a breaking change. Existing region XML continues to parse, sign, verify, render. The new discipline applies to additions.
Section 12Roadmap & open frontiers
What this delivery completes; what it makes immediately possible; what remains open.
Completed in this delivery
- Five block-kind XML conventions with strict separation
- The TABLE_SPECIFICATIONS spine schema
- Six projection XSL stylesheets covering five block kinds + an HTML renderer
- A compose driver that orchestrates the projections via xsltproc
- Eight worked block examples from Rob's real 25-year practice
- A composed reference spine (77 rows) demonstrating self-referencing graph properties
- This documentation
Immediately possible (next deliveries)
- address-block and binding-block — complete the eight-block model. Address blocks declare pure coordinates without payload; binding blocks resolve coordinates to physical sources (Oracle, MinIO, REST, file). Projection XSLs for both. Adds the federation-of-stores layer.
- Cryptographic signing per block. Each block gets a
<signature> direct child, signed canonical form via XMLSerializer, fingerprint visible in the spine ext fields. Plumb publisher attribution through to spine row provenance.
- RNG or XSD schemas for each block kind, enforcing strict separation at the validator layer rather than just at the documentation layer.
- Canvas feature for spine rendering. Load a composed spine into MR-CANVAS-v0.8 via a new
feature-spine-renderer.xml; clicking any row navigates to the source block. The spine becomes interactive.
- Reverse projection. Project from the spine BACK into a specific block kind. Given a spine query result, emit the equivalent schema-block or data-block. The inverse of the forward projections.
Open frontiers
- Live binding to Oracle 26ai Free instances. A binding-block whose target is an Oracle external table; the projection XSL becomes a SQL query generator that produces a view definition over the external source. The spine becomes a queryable layer over live Oracle data, in line with MEMEROOT-REF-2026-001.
- Multi-database federation. Multiple binding-blocks targeting different databases — Oracle, Postgres, DuckDB, SQLite. The spine federates them via database links and pipelined functions, with no replication.
- Standards proposal. The block-kind taxonomy + spine projection pattern is not Memeroot-specific. It could be the basis of a broader standard for composable structured-content interchange. The substrate just needs naming.
- Substrate-native LLM training. Training corpora composed of typed blocks with strict separation and total provenance. Models trained on this can emit blocks that round-trip the projection; the spine becomes the dataset.