graph { graph [engine:dot rankdir:LR clusterize:false applyCss:dark] mdt -> transclusion [reverse: false] mdt -> ideas [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec -> The_idea [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec -> Goals [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec -> mdt_as_Markdown [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec -> compile__ [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec -> Runner [reverse: false] Runner -> Document [reverse: false] Runner -> Usage___Iteration [reverse: false] Runner -> Usage___Trail_navigation [reverse: false] Runner -> Trail_id [reverse: false] Runner -> Usage___Extruction_evaluation_with_adapters [reverse: false] Runner -> Usage___Error_recovery [reverse: false] Runner -> Usage___Adapter_with___mdt_label_ [reverse: false] Runner -> Usage___State_across_extructions [reverse: false] Runner -> Phases [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= Fragment [reverse: false] Fragment *= expand___traversal [reverse: false] Fragment *= Lazy_guarantees [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= Extruction [reverse: false] Extruction *= Transparency_semantics [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= Error_Handling [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= Open_Questions [reverse: false] Open_Questions *= 1__What_is__context__for_ [reverse: false] Open_Questions *= 2__Extruction_label_semantics [reverse: false] Open_Questions *= 3__When_will_extruction_bodies_activate_ [reverse: false] Open_Questions *= 4__Verbatim_vs_canonicalized_body [reverse: false] Open_Questions *= 5___hasChildren__and_extructions [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= App_Integration [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= Extruction_Evaluation [reverse: false] Extruction_Evaluation *= evalBody [reverse: false] Extruction_Evaluation *= Extruction_return_value____insert________inject____built_ins [reverse: false] Extruction_return_value____insert________inject____built_ins *= insert_children__ [reverse: false] Extruction_return_value____insert________inject____built_ins *= inject_text__ [reverse: false] Extruction_return_value____insert________inject____built_ins *= children____recursively_resolved_child_subtree [reverse: false] Extruction_return_value____insert________inject____built_ins *= insertRefsAsSubtree_items__opts___ [reverse: false] Extruction_return_value____insert________inject____built_ins *= insertNljson_collection__opts___ [reverse: false] Extruction_return_value____insert________inject____built_ins *= insertRefsAsList_items__opts___ [reverse: false] Extruction_return_value____insert________inject____built_ins *= insertRefsAsNljson_items__optsOrFn___ [reverse: false] Extruction_return_value____insert________inject____built_ins *= buildUrl_content__mimeType___ [reverse: false] Extruction_return_value____insert________inject____built_ins *= Mixed_output [reverse: false] Extruction_return_value____insert________inject____built_ins *= Return_nothing [reverse: false] Extruction_return_value____insert________inject____built_ins *= State_still_via__mdtState_ [reverse: false] Extruction_return_value____insert________inject____built_ins *= Adapters____search____searchVotes____votesAsRefs_ [reverse: false] Extruction_return_value____insert________inject____built_ins *= Command_contract___all_verbs [reverse: false] Extruction_Evaluation *= hasChildren___extruction_evaluation [reverse: false] Extruction_Evaluation *= Error_behavior [reverse: false] Extruction_Evaluation *= buildInsertFragment_serialization [reverse: false] Extruction_Evaluation *= Probes [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= Search_Adapter [reverse: false] Search_Adapter *= glassSearchRunAsync [reverse: false] Search_Adapter *= search___adapter [reverse: false] Search_Adapter *= Completion_detection [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= Adapter_Pattern [reverse: false] Adapter_Pattern *= How_it_works [reverse: false] Adapter_Pattern *= Naming_rules [reverse: false] Adapter_Pattern *= Return_protocol [reverse: false] Adapter_Pattern *= Adapter_conventions [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= Example_adapters [reverse: false] Example_adapters *= 1__Simple_lookup__sync_ [reverse: false] Example_adapters *= 2__Search_adapter [reverse: false] Example_adapters *= 3__HTTP_fetch [reverse: false] Example_adapters *= 4__Database_query [reverse: false] Example_adapters *= 5__State_access [reverse: false] Example_adapters *= 6__Composition___multiple_adapters [reverse: false] Example_adapters *= 7__Using___mdt_label__to_drive_adapters [reverse: false] Example_adapters *= Key_constraints [reverse: false] Example_adapters *= 6__E2E_tests [reverse: false] mdt___Markdown_Construction_Pseudo_Code_Spec *= Conversion_tree___transclusion_provenance [reverse: false] Conversion_tree___transclusion_provenance *= sourceFragment_field [reverse: false] Conversion_tree___transclusion_provenance *= Extruction_protocol___insert___extended [reverse: false] Conversion_tree___transclusion_provenance *= Consumer_collects_conversion_tree [reverse: false] Conversion_tree___transclusion_provenance *= Rendering_uses_conversion_tree [reverse: false] Conversion_tree___transclusion_provenance *= Trail_format_conversion [reverse: false] Conversion_tree___transclusion_provenance *= Changed_files [reverse: false] mdt [z: 9.5 @html: "
mdt
• mdd transclusion
• its runnable in nodejs
• mq-declarative-actor can run it
• sphere of fragments
• dynamic paper, space
• presented incrementally
" nomen: "mdt"] transclusion [z: 4.75 @html: "
transclusion
• mdd transclusion is value.
• using thefragment://./url-in-headin⸨fragment://./url-in-headin⸩institute, fragments can be referenced
• this means a tertiary virtual mdd paper
can be created, which opens
opportunities:
• on render of the mdt, it can render the
referenced fragments as needed; maybe
add "buttons"
• on the other hand: each fragment
(anywhere) can have all mdt's (where its
referenced) at disposal
• the referencing anchor derives
information also by its position in the
structure of the mdt markdown tree
• its similiar tosymmetric functional tree⸨symmetric functional tree⸩
• see meta-data
• see usage forfragment://voting⸨fragment://voting⸩
• valid mdd + m4
• at instruction point (= heading)
• insert select
• inject select
• #/paper/paper/mechanism/md⸨#/paper/paper/mechanism/md⸩
• see TOT
" nomen: "transclusion"] ideas [z: 4.75 @html: "
ideas
• an extruction can have the codeblock and
also text
• insert is fetching cached content of
fragments
• backend?
• final mdd will be produced?
• makes sense for space,
" nomen: "ideas"] mdt___Markdown_Construction_Pseudo_Code_Spec [z: 9.5 @html: "
mdt — Markdown Construction Pseudo-Code
Spec

Pure JavaScript library for a markdown construction pseudo-code language . Markdown is the surface syntax. # ${...} headings are extructions — labeled markers that produce no
output; bodies use ```javascript code blocks for eval.The library follows a compile / runner split:
•  compile(mdtText, { remark }) — static analysis, returns a Runner 
• The Runner is a function — call it with context and
opts to get a Document , which lazily yields expandable Fragment objects
All functions are pure — no mutation of inputs, no side
effects, no classes, all external
dependencies passed as arguments.
" nomen: "mdt — Markdown Construction Pseudo-Code Spec"] The_idea [z: 4.75 @html: "
The idea
• sphere of fragments
• dynamic markdown OLAP
The # ${...} construct is called an extruction — a coined term for a labeled heading
marker that produces no output; the body
uses ```javascript code blocks for evaluation.The name evolved through several
candidates during design:
•  expansion — suggests something that unfolds when
activated
•  diversion — content that diverts from normal
output flow
•  fragment instruction — a fragment that carries an instruction
•  generator — evokes generating content from the
label
•  extruction — chosen; portmanteau hinting at
"extract" /
"execute" and
"construction"
Other ideas considered: hatch, vault,
pocket, slot, well, lens, scope, portal,
embed, injection, graft, splice, yield,
emit, render.
" nomen: "The idea"] Goals [z: 4.75 @html: "
Goals
• Markdown is the surface language
•  # ${...} headings are extructions — labeled markers, filtered from output;
bodies use ```javascript code blocks for eval
•  Lazy by default : only process what the consumer pulls
•  Pure functions throughout : all dependencies are explicit
arguments, never closed-over imports
" nomen: "Goals"] mdt_as_Markdown [z: 4.75 @html: "
mdt as Markdown
Every .mdd file is also valid .md . Extructions ( # ${label} ) render as ordinary visible headings.
Standard markdown renderers see no
special syntax — the mdt semantics are
invisible to them.
" nomen: "mdt as Markdown"] compile__ [z: 4.75 @html: "
compile

 compile(mdtMd, { remark }) →
Runner 

Single entry point. Takes raw mdt
markdown text and a remark instance (for .parse() ). Returns a Runner — no evaluation happens yet.
 import { compile } from
'./mdt/mdt.js' import { remark } from
'remark' const runner =
compile(sourceMd, { remark }) 

Compile-time errors (thrown synchronously):
• Unparseable markdown (remark parse
failure)
During compilation, headings whose text
starts with ${ are marked as extructions. They are
tracked separately but no transform is
applied — the remark AST is kept as-is.
" nomen: "compile"] Runner [z: 4.75 @html: "
Runner

 runner(context, opts?) →
Document 

The runner is a function. Call it with
context and options to get a Document — the entry point for navigating the
document tree. No processing happens
until you pull from the iterable or call
navigate. opts carries run-time dependencies:
 opts = { sanitizeName: (str)
=> str.toLowerCase().replace(/\\W+/g,
'-').replace(/^-+|-+$/g, '') } 

 sanitizeName defaults to the function shown
(lowercase, non-word chars to - , leading/trailing dashes trimmed).
Callers can override. opts.loadRefBody :
•  async (item, targetDepth) →
string 
— fetches the body markdown for one insertRefsAsSubtree item. Called lazily, only when a
Fragment's expand() is iterated by the consumer.
•  targetDepth is the heading depth at which the
Fragment's root heading is emitted; the
returned body must have its own root
heading stripped and its nested
subheadings shifted so root+1 lands at targetDepth+1 , root+2 at targetDepth+2 , etc.
• App integration: compose existing loadFragment(...) + relevelFragment(text, targetDepth
- 1) 
(bare import from player-utils.js , not ssss.relevelFragment ) + a regex strip of the root heading. relevelFragment(text, N) puts the source root at depth N+1 , so passing targetDepth - 1 puts the root at targetDepth — after the root-strip, the source's
root+1 headings are what's left,
correctly landing at targetDepth+1 .
" nomen: "Runner"] Document [z: 2.375 @html: "
Document
A Document is both an async iterable (yields root-level Fragments) and a navigation hub (find fragments by trail-id):
 doc【Symbol.asyncIterator】() →
AsyncIterable<Fragment>
doc.find(trail) → Fragment
| undefined doc.children(trail)
→ AsyncIterable<Fragment>
doc.preamble →
string 

•  preamble — any text in the source that appears
before the first heading. Empty string
if there is none.
•  find(trail) — walks lazily along the matching prefix
only. At each level it compares the next
trail segment against child sanitized
names and expandsonlythe matching child, abandoning the rest.
Cost is O(path length) expansions, not
O(document). Returns undefined if no match.
•  children(trail)  find(trail)?.expand() .
A Document is stateless and re-iterable — each call to the runner produces a
fresh Document, and each iteration
re-derives from the compiled tree.
" nomen: "Document"] Usage___Iteration [z: 2.375 @html: "
Usage — Iteration

 const doc = runner({ user }); for
await (const section of doc) { //
section.heading → "# Chapter
1" // section.body → "Some
text..." // section.toString() →
"# Chapter 1\\n\\nSome text..."
for await (const child of
section.expand()) { // child.heading
→ "## Section 1.1" //
child.headingLevel → 2 // child.body
→ "Details..." } } 

" nomen: "Usage — Iteration"] Usage___Trail_navigation [z: 2.375 @html: "
Usage — Trail navigation

 const doc = runner( { user },
{ sanitizeName: (s) =>
s.toLowerCase().replace(/\\W+/g,
"-"), }, ); // Find a
heading by trail-id const section =
doc.find("getting-started/installation");
for await (const step of
section.expand()) { // immediate
children of ## Installation } // Or
shortcut: get children directly for
await (const step of
doc.children("getting-started/installation"))
{ // same result } // Preamble text
before the first heading
console.log(doc.preamble); 

" nomen: "Usage — Trail navigation"] Trail_id [z: 2.375 @html: "
Trail-id
A trail-id is a / -separated path of sanitized heading
names that uniquely identifies a heading
in the document hierarchy:
HeadingTrail
 # Getting Started  "getting-started" 
 ## Installation  "getting-started/installation" 
 ### Linux  "getting-started/installation/linux" 
 ### macOS  "getting-started/installation/macos" 
 ## Usage  "getting-started/usage" 
The trail is constructed with the same stack algorithm used by getHeadingTrail in the existing codebase:
• Walk all heading nodes depth-first (in
document order)
• Maintain a stack of { level, sanitized } entries
• When a heading at level N is
encountered, pop all stack entries where level >= N , then push this heading
• The trail is stack.map(e =>
e.sanitized).join("/") 
Extructions ( # ${label} ) are skipped by the trail algorithm —
they produce no output and don't
contribute to the stack. A ## Details after an extruction ## ${sidebar} at the same level gets trail "intro/details" , not "intro/sidebar/details" .Traversal stops at the first match find() and children() return the section at the exact trail
without pre-processing the entire
document. Fragments past the match are
not materialized.
" nomen: "Trail-id"] Usage___Extruction_evaluation_with_adapters [z: 2.375 @html: "
Usage — Extruction evaluation with
adapters

When evalFn is provided, extruction bodies run as
JavaScript and can produce output via
the insert protocol:
 import { compile } from
'./mdt/mdt.js' import { evalBody } from
'./mdt/eval-body.js' import { remark }
from 'remark' const md = `# ${greeting}
\\`\\`\\`javascript const name = _mdt_label
return insert(\\`Hello **\\${name}**\\`)
\\`\\`\\` # Results ## ${search mdd}
\\`\\`\\`javascript const items = await
search("mdd") return
insert(items.map(i =>
i.uri).join("\\\\n")) \\`\\`\\` ##
Total \\`\\`\\`javascript return
insert(String(total)) \\`\\`\\` ` const
search = async (q) => 【 { name:
"file1", uri:
"#/paper/file1" }, { name:
"file2", uri:
"#/paper/file2" }, 】 const
total = 42 const runner = compile(md, {
remark }) const doc = runner({ search,
total }, { evalFn: evalBody }) for
await (const section of doc) {
console.log(section.toString()) //
"${greeting}" → "<!--
greeting -->\\n\\nHello **world**"
// "Results" → normal heading,
expanded below for await (const child
of section.expand()) { //
"${search mdd}" →
"#/paper/file1\\n#/paper/file2"
// "Total" → "42"
} } 

The extruction body return insert(value) yields one or more Fragment-like objects
directly into the output. Any await -able function in context is an adapter
 search , total , and _mdt_label all coexist as named bindings.
" nomen: "Usage — Extruction evaluation with adapters"] Usage___Error_recovery [z: 2.375 @html: "
Usage — Error recovery
When an extruction body throws, onExtructionError lets you log and skip instead of
crashing the iteration:
 const doc = runner({ search }, {
evalFn: evalBody, onExtructionError:
(err, headingNode) => {
console.warn( \\`Extruction
"\\${headingNode.data?.label}"
failed:\\`, err.message, ) },
}) for await (const section of doc) {
// Sections after the failing extruction
still appear } 

Without the callback, errors propagate
to the consumer's for await loop. With the callback, the failing
extruction is silently dropped and
iteration continues with the next
heading. The heading node gives access
to the position ( headingNode.position ) for source-mapped diagnostics.
" nomen: "Usage — Error recovery"] Usage___Adapter_with___mdt_label_ [z: 2.375 @html: "
Usage — Adapter with
The _mdt_label binding lets one adapter serve multiple
extruction variants:
 const md = `# ${search mdd}
\\`\\`\\`javascript const items = await
search(_mdt_label) return insert(
items.map(i => "- " +
i.uri). join("\\\\n")) \\`\\`\\` #
${search js} \\`\\`\\`javascript const
items = await search(_mdt_label) return
insert( items.map(i => "- "
+ i.name). join("\\\\n")) \\`\\`\\`
` const search = async (q) => { if
(q === "search mdd") return 【{
name: "readme", uri:
"#/readme" }】 return 【{
name: "main.js", uri:
"#/main.js" }】 } const runner
= compile(md, { remark }) const doc =
runner({ search }, { evalFn: evalBody
}) 

The same search adapter is called with the label as its
argument — no need to hardcode adapter
names per extruction.
" nomen: "Usage — Adapter with `_mdt_label`"] Usage___State_across_extructions [z: 2.375 @html: "
Usage — State across extructions
The runner automatically injects mdtState — a plain object that persists across
extruction evaluations within the same
document:
 const md = `# ${init}
\\`\\`\\`javascript mdtState.counter = 0
mdtState.items = 【"a",
"b", "c"】 \\`\\`\\` #
${first} \\`\\`\\`javascript
mdtState.counter++ return insert( \\`Item
\\${mdtState.counter}:
\\${mdtState.items【0】}\\` ) \\`\\`\\` #
${second} \\`\\`\\`javascript
mdtState.counter++ return insert( \\`Item
\\${mdtState.counter}:
\\${mdtState.items【1】}\\` ) \\`\\`\\` `;
const runner = compile(md, { remark });
const doc = runner({}, { evalFn:
evalBody }); for await (const section
of doc) {
console.log(section.toString()); //
"${init}" → transparent (no
return/insert) // "${first}"
→ "Item 1: a" //
"${second}" → "Item 2:
b" } 

 mdtState is just a {} — the extruction body sets properties on
it, and subsequent evaluations read them
back. It's automatically available in
every extruction body without being
added to the runner context.Callers can pre-populate mdtState by passing it in the context:
 const doc = runner( { mdtState:
{ repo: "my-repo", branch:
"main" } }, { evalFn:
evalBody }, ); 


 ## ${header} \\`\\`\\`javascript
return insert( \\`Repo:
\\${mdtState.repo}, branch:
\\${mdtState.branch}\\` ) \\`\\`\\` 

This is useful when extructions need
shared initialization or cross-section
communication without resorting to
global variables. Why this works:  mdtState is a single object stored on runnerContext . Each eval call spreads runnerContext into the function parameters, but the
spread copies the reference — all
evaluations share the same mdtState object. Property mutations
(set/add/delete) persist; reassigning mdtState = ... would only affect the local parameter.
" nomen: "Usage — State across extructions"] Phases [z: 2.375 @html: "
Phases
The runner materializes the document in
phases:
PhaseWhat's yieldedWork done
1Root headings (level # )Walk top-level children, skip
extructions
2+Children of a sectionWalk child headings, skip extructions,
yield Fragments
No phase happens until the consumer
pulls.
" nomen: "Phases"] Fragment [z: 4.75 @html: "
Fragment
A heading + its immediate body content.
A fragment is the core unit the runner
yields and the consumer navigates.
 { trail:
"getting-started/installation",
// trail-id identifying this heading
heading: "# Chapter 1",
// raw markdown heading string
headingLevel: 1, // number
of # characters body: "Some
introductory text.", //
canonicalized markdown body (no
children) hasChildren: true,
// does this fragment have expandable
children? expand():
AsyncIterable<Fragment>, // yields
child fragments toString(): "#
Chapter 1\\n\\nSome introductory
text." // heading + body } 

•  trail — the trail-id that uniquely identifies
this heading in the document hierarchy.
Computed lazily using the stack
algorithm when the fragment is first
materialized
•  heading — the heading as markdown source (e.g. "## Details" )
•  headingLevel — depth (1 for # , 2 for ## , etc.)
•  body — the immediate body text, canonicalized (parsed nodes rendered back to
markdown). Not byte-identical to source:
remark normalizes list markers, emphasis
characters, wrapping. If verbatim
fidelity is required, use the source
position ( node.position ) to slice the original text. Does NOT
include child fragments.
•  hasChildren — quick check without triggering
expansion
•  expand() — returns an async iterable of child Fragment objects. Each child is itself expandable
and carries its own trail.
•  toString() — concatenates heading + "\\n\\n" +
body 
, rendered as markdown. Convenience for
getting a fragment's full self-contained
markdown.
AST source: currently the fragment is materialized
from remark's parsed AST. In the future
it could come from the ast-nodes
database ( cache_ast_lake_nodes with sem = 'heading' ), where each row carries { id, mt, sem, num1, num2, ref
and nomen is derived from ref . The fragment shape is designed to be
mappable to/from that schema: trail  id , heading  ref , headingLevel  sem .
" nomen: "Fragment"] expand___traversal [z: 2.375 @html: "
expand traversal
 expand() walks the remark AST child heading
nodes:
• Walk child nodes left-to-right in
document order.
• When hitting a heading that is not an extruction → yield a child Fragment . Its body is the run of non-heading
nodes up to the next heading at the same
level.
• When hitting an extruction heading → skip (inert, no output).
•  Other nodes (paragraphs, lists, etc.) → accumulate
into the current fragment's body.
Body boundary rule: content before the first child heading
belongs to the parent's body ; content between child headingNand the next heading belongs to childN's body .
" nomen: "expand traversal"] Lazy_guarantees [z: 2.375 @html: "
Lazy guarantees
•  expand() does nothing until iterated
• Iterating past the first few fragments
doesn't process later fragments
" nomen: "Lazy guarantees"] Extruction [z: 4.75 @html: "
Extruction

 ## ${label} \\`\\`\\`javascript //
body code — only ```javascript blocks
are evaluated \\`\\`\\` 

An extruction is a # ${...} heading. When evalFn is provided, the body is evaluated as
JavaScript — but only code inside is extracted. Any other markdown content
in the body is ignored. Without evalFn , the extruction and its body are
silently dropped.
PropertyValue
DetectionHeading text starts with ${ 
BodyJavaScript code in ```javascript code blocks (only when evalFn is
provided)
EffectRemoved from output; children promoted
The data.label (text between ${} ) is available on the heading node for
future processing but has no current
effect.
" nomen: "Extruction"] Transparency_semantics [z: 2.375 @html: "
Transparency semantics
Extructions are fully transparent — they produce no output and their body
content is silently dropped, but
non-extruction headings nested under an
extruction are promoted to the nearest non-extruction ancestor's expand() output. Their trail is computed as if
the extruction doesn't exist.Implementation: skipExtructionBody(startIdx,
rootChildren) 
advances past an extruction's
non-heading content but stops at any
heading (a promoted child), rather than
skipping the entire subtree. This is
used by expandChildren , collectBodyNodes , and hasNonExtructionChild to maintain consistency.
" nomen: "Transparency semantics"] Error_Handling [z: 4.75 @html: "
Error Handling
Compile-time (thrown by compile() ):
• Unparseable markdown (remark parse
failure)
Runtime (caught by onExtructionError callback):
• Syntax errors in extruction body JS
• Runtime exceptions during extruction
evaluation
When an extruction body throws during
evaluation, the behavior depends on the
presence of onExtructionError :
CallbackBehavior
Provided Error is passed to onExtructionError(err,
headingNode) 
; the extruction is treated as transparent (body skipped, children promoted).
Iteration continues.
Not provided ( null /omitted)Error propagates to the consumer's for await loop (backward compatible).
In children resolution, an errored child extruction
follows the same rule — treated as
transparent, its children promoted into
the parent's children output.All errors include the source position ( node.position ) for debugging.
" nomen: "Error Handling"] Open_Questions [z: 4.75 @html: "
Open Questions
" nomen: "Open Questions"] 1__What_is__context__for_ [z: 2.375 @html: "
1. What is
Resolved:  context is state — a bag of global variables that the
document can reference. With evalFn , extruction bodies can access context
keys as named parameters. Without evalFn , context is accepted but unused.The runner signature stays runner(context, opts?) . With no active extructions, context is accepted but unused — a
forward-looking parameter.
" nomen: "1. What is `context` for?"] 2__Extruction_label_semantics [z: 2.375 @html: "
2. Extruction label semantics
Deferred.  data.label is a free-form string — the text between ${} . Its semantics are intentionally
undefined until extruction evaluation is
designed. Currently just stored, no
effect.
" nomen: "2. Extruction label semantics"] 3__When_will_extruction_bodies_activate_ [z: 2.375 @html: "
3. When will extruction bodies activate?
Resolved. Extruction bodies are evaluated as
JavaScript when evalFn is provided. Only ```javascript code blocks within the body are
extracted — non-javascript code blocks
and other markdown content are ignored.
Without evalFn , the body remains inert (silently
dropped).
" nomen: "3. When will extruction bodies activate?"] 4__Verbatim_vs_canonicalized_body [z: 2.375 @html: "
4. Verbatim vs canonicalized body
Resolved.  body is canonicalized by default
(re-stringified remark nodes). Source
position ( node.position ) is the escape hatch for verbatim
access. No default flip — canonicalized
is the correct default because consumers
should get consistent, predictable
markdown output. If verbatim is needed,
slice the original text using source
offsets.
" nomen: "4. Verbatim vs canonicalized body"] 5___hasChildren__and_extructions [z: 2.375 @html: "
5.
Resolved — extructions are fully transparent with child promotion. Extructions are skipped from both output
and navigation. Non-extruction headings
nested under an extruction are promoted to the parent's expand() output:
•  hasChildren reports what expand() would yield — this includes promoted
children under extructions.
• Child headings nested under an
extruction get their trail computed as
if the extruction doesn't exist — they
attach to the nearest non-extruction
ancestor heading.
• Extruction body content is still
silently dropped; only the promoted
heading (and its own subtree) survives.
•  skipExtructionBody() is the shared helper that implements
this: given an extruction heading index,
it advances past non-heading body
content but returns at the first heading
(promoted child) rather than skipping
the entire subtree.
• Consistency invariant: expand() , hasChildren , collectBodyNodes , and findInHeadings all agree on which headings are
reachable.
• Rationale: extructions are inert markers
by default; their body is dropped (or
evaluated with evalFn ), but document structure under them is
preserved.
" nomen: "5. `hasChildren` and extructions"] App_Integration [z: 4.75 @html: "
App Integration
The MDT library is integrated into player-paper.js at the "mdt" case of the extension switch (line 876).
When a .mdt file is opened:
•  Dynamic imports : remark + remark-parse loaded from CDN ( cdn.jsdelivr.net ); compile imported from ./mdt/mdt.js 
•  Fetch : file content fetched via ssss.fetchWithETag() with ETag caching
•  Compile : compile(data, { remark })  Runner 
•  Run : runner(STATE)  Document (STATE serves as context)
•  Rebuild clean markdown : fragments recursively collected via collectFragments() async generator, each fragment's toString() produces heading + body with extructions
already filtered
•  Render : clean markdown rendered via ssss.renderMarkdown() 
•  Post-process : heading tabindex, relative image URL
resolution
The current integration uses the
browser's dynamic import() for remark (same CDN source as mdd.mjs ). The context parameter passes the app's STATE object,
with adapters mixed in for extruction
evaluation.
" nomen: "App Integration"] Extruction_Evaluation [z: 4.75 @html: "
Extruction Evaluation
Extruction bodies can be evaluated as
JavaScript at runtime when the evalFn option is passed to the runner. This
enables # ${...} headings to produce dynamic content.
" nomen: "Extruction Evaluation"] evalBody [z: 2.375 @html: "
evalBody
 mdt/eval-body.js exports the default evaluation function:
 evalBody(bodyText, context) →
Promise<any> 

It uses the AsyncFunction constructor (same pattern as evalJsFilterWithContext in filter-base.js ) to evaluate the body text as JS code
with the context keys available as named
parameters.
 import { evalBody } from
"./mdt/eval-body.js"; const
doc = runner({ search, STATE }, {
evalFn: evalBody }); 

Inside an extruction body, any key from
the context is directly accessible:
 ## ${the list} \\`\\`\\`javascript
const x = await search("mdd")
return insert( x.map(i =>
i.uri).join("\\n"))
\\`\\`\\` 

" nomen: "evalBody"] Extruction_return_value____insert________inject____built_ins [z: 2.375 @html: "
Extruction return value —
When evalFn is provided, the extruction body has
access to auto-injected helpers and data
(like _mdt_label , mdtState , and log ):
•  [object Object] — pipe Fragment-like objects directly
into the output
•  [object Object] — produce a single raw-body Fragment
with no heading
•  [object Object] — markdown text of the extruction's
child subtree (headings between this
extruction and the next heading at
same/higher depth)
" nomen: "Extruction return value — `insert` / `inject` built-ins"] insert_children__ [z: 1.1875 @html: "
insertchildren
Takes one or more Fragment-like objects
and yields each as-is into the output
stream. No wrapping, no heading comment
— the caller has full control:
 ## ${search results}
\\`\\`\\`javascript const items = await
search("mdd") return
insert(items.map(r => ({ trail:
_mdt_label + "/" + r.id,
heading: "### " + r.name,
headingLevel: 3, body: r.description,
hasChildren: false, expand: () =>
(async function* {})(), toString: ()
=> "### " + r.name +
"\\n\\n" + r.description, })))
\\`\\`\\` 

Pass a single fragment or an array — insert() handles both:
 return insert(singleFrag); return
insert(【fragA, fragB, fragC】); 

" nomen: "`insertchildren`"] inject_text__ [z: 1.1875 @html: "
injecttext
Takes a string and yields a single
raw-body Fragment with no heading, no
trail, no wrapper:
 ## ${notice} \\`\\`\\`javascript
return inject("> **Note:**
generated from live data.")
\\`\\`\\` 

The Fragment has heading: "" , headingLevel: 0 , trail: "" , and toString() returns the raw body.
" nomen: "`injecttext`"] children____recursively_resolved_child_subtree [z: 1.1875 @html: "
children
The children variable holds the resolved output of
the extruction's child subtree — all
headings between this extruction and the
next heading at the same or higher
depth. Non-heading body text after the
extruction heading is not included (that's the bodyText passed to evalFn ).Resolution is recursive children is computed by walking the child tree
and processing each node:
Child typeTreatment
Extruction (with result)Evaluated with its own recursive children ; its output ( inject / insert bodies) is stringified and included
Extruction (transparent — undefined /no return)Body skipped; children promoted and
recursively resolved
Extruction (suppressed — null )Entire subtree dropped — children do not
appear in parent's children 
Extruction (errored, with onExtructionError )Caught; treated as transparent —
children promoted (same as skipExtructionBody )
Regular heading Heading text + body text preserved as
markdown; its own child subtree
recursively resolved for any nested
extructions
This means extructions at any depth are
fully evaluated — a ##### ${...} deep under a regular #### heading will still produce its resolved
output.A common pattern is to pipe children
through insert() :
 ## ${list of todos}
\\`\\`\\`javascript return
【inject("> Generated
list:\\n\\n"), insert(children)】
\\`\\`\\` 

 children is an empty string "" when:
• The extruction has no child headings
• The extruction is at root level with no
children
Non-extruction headings are included as
original markdown (source positions
preserve formatting). Extruction
headings themselves never appear in the
output — they're transparent, only their
resolved content is included.
" nomen: "`children` — recursively resolved child subtree"] insertRefsAsSubtree_items__opts___ [z: 1.1875 @html: "
insertRefsAsSubtreeitems, opts?
Turn an array of fragment refs
(typically await search(...) results) into child-depth heading
Fragments with lazy body-fetch :
 ## ${search fragments; do}
\\`\\`\\`javascript return
【insertRefsAsSubtree(await
search(_mdt_label))】 \\`\\`\\` 

Each item becomes ONE Fragment one level below the extruction ( extruction.depth + 1 ), so the results nest as children of
the current level. The Fragment's body
is empty at yield-time; the fetch
happens only inside its expand() — i.e. only when the render pipeline
walks into that subtree. Depth is
clamped at 6 (markdown's maximum heading
level).
 ## insertRefsAsSubtree ←
depth 2, visible parent ###
${insertRefsAsSubtree} ← depth 3,
extruction (filtered from output) ####
auth ← depth 4, one
Fragment per item ##### …transcluded
body… ← depth 5+, from
loadRefBody 

This is the only verb whose heading is
real markdown — every other verb emits
an HTML-comment heading, so its depth is
invisible. Item contract (minimum):
FieldPurpose
 nomen / ref / trail / name Heading text — resolves in order: nomen (pre-computed) → ref.split(";").at(-1) (leaf of the semicolon-trail, matching cmdDashboard.js / cmdTreeview.js convention) → trail.at(-1) (parsed-array form) → name (URL-style, last-resort fallback)
 fn Source file path
 trail (array)Preferred — used to build canonical
refId
 num1 (number)Fallback when trail is absent
Items missing name / ref , or without both fn and ( trail or num1 ), are skipped with console.warn . If every item is skipped, a visible\nblockquote is emitted explaining why — the verb never fails
silently.The common cause is feeding it the wrong
search source: files results ( {name, uri, fn,
type:"file"} 
) carry no trail / num1 , so there is no subtree to resolve. Use
a fragments query, whose items carry nomen / trail / num1 / fn . opts:
FieldPurpose
 depth Absolute override of the auto depth ( extruction.depth + 1 )
Runner opt required:  runner(ctx, { evalFn, loadRefBody
}) 
. If loadRefBody is not provided, each Fragment renders
heading-only.
" nomen: "`insertRefsAsSubtreeitems, opts?`"] insertNljson_collection__opts___ [z: 1.1875 @html: "
insertNljsoncollection, opts?
Serialize a collection as
newline-delimited JSON inside an ```nljson fence — one JSON object per line:
 ## ${rows} \\`\\`\\`javascript
return 【insertNljson(【{ a: 1 }, { b: 2
}】)】 \\`\\`\\` 


 {"a":1}
{"b":2} 

A single non-array value is wrapped.
This is a raw passthrough — values are serialized as given, so
nested objects and arrays survive. That
makes it unsuitable for feeding a table
directly: insertNljson(await
search(...)) 
emits trail arrays, and Tabulator's html formatter throws Formatter has returned a type of
object 
. Use insertRefsAsNljson for table-bound ref data, or pick scalar
fields yourself.
" nomen: "`insertNljsoncollection, opts?`"] insertRefsAsList_items__opts___ [z: 1.1875 @html: "
insertRefsAsListitems, opts?
Render an array of refs as a markdown
bullet list — a flat alternative to insertRefsAsSubtree with no lazy fetch:
 ## ${links} \\`\\`\\`javascript
return 【insertRefsAsList(await
search(_mdt_label))】 \\`\\`\\` 


 - 【auth】(#/paper/todo.mdd/auth)
{{"platba":{"suma":42}}}
- 【login】(#/paper/a.mdd) - plain 

Labels resolve with the same 4-step rule
as insertRefsAsSubtree . An item with uri becomes a markdown link; without one it
stays plain text. Items with no
resolvable label are skipped with console.warn .
optsPurpose
 bullet List marker, default "-" 
 data  false suppresses the {…} data suffix
 source Conversion-tree provenance tag
" nomen: "`insertRefsAsListitems, opts?`"] insertRefsAsNljson_items__optsOrFn___ [z: 1.1875 @html: "
insertRefsAsNljsonitems, optsOrFn?
Render an array of refs as nljson rows —
reuses insertNljson 's fence, but builds each row from the
ref and guarantees table-safe scalar cells :
 ## ${table} \\`\\`\\`javascript
return 【insertRefsAsNljson(await
search(_mdt_label))】 \\`\\`\\` 


 {"link":"<a
HREF=\\"#/paper/todo.mdd/auth\\">auth</a>","data":"{\\"platba\\":{\\"suma\\":42}}"} 

 link is an HTML anchor (not a markdown link) because nljson
usually feeds a table — the table needs columnDefaults: { formatter:
'html' } 
to render it. The uri is attribute-escaped ( &  &amp; , "  &quot; ).Every row value is flattened before
output: any object or array becomes a
JSON string. This is what keeps
Tabulator's html formatter from throwing on trail arrays or nested data . Second argument — object or function. A bare function is shorthand for { extend: fn } :
 \\`\\`\\`javascript return 【
insertRefsAsNljson(mdtState.items,
function addAdditionalProperties(i) {
const data = i.data ? JSON.parse(i.data)
: undefined return { suma:
data?.platba?.suma, data:
JSON.stringify(data), } }), 】
\\`\\`\\` 

 extend(item, row) receives the raw item first (so item.data is the untouched string) plus the base
row, and its returned props are merged
over the auto-built ones — the example
above replaces the auto data . Keys whose value is undefined are dropped from the row rather than
emitted as null , so ragged rows are normal.
optsPurpose
 extend  (item, row) => ({…}) — per-item extra props, merged last. A
bare function argument is shorthand for
this
 fields Array of item field names to copy
through, e.g. 【'scaledTs'】 
 data  false drops the auto data column
 map  (row, item) => row — replaces the whole row; runs after extend and sees parsed values before flattening
 source Conversion-tree provenance tag
" nomen: "`insertRefsAsNljsonitems, optsOrFn?`"] buildUrl_content__mimeType___ [z: 1.1875 @html: "
buildUrlcontent, mimeType?
Not a command — a plain helper returning
a base64 data URI via btoa() . Defaults to text/plain :
 \\`\\`\\`javascript return
【inject(`【download】(${buildUrl(JSON.stringify(rows),
"application/json")})`)】
\\`\\`\\` 

" nomen: "`buildUrlcontent, mimeType?`"] Mixed_output [z: 1.1875 @html: "
Mixed output
Return an array of calls to produce
multiple items in sequence:
 ## ${mixed} \\`\\`\\`javascript
const items = await
search("mdd") const cards =
items.map(r => ({ /* fragment shape
*/ })) return 【inject("> Preview
below:\\n\\n"), insert(cards)】
\\`\\`\\` 

Each item in the array is a command
object produced by any of the verbs — insert() , inject() , insertNljson() , insertRefsAsList() , insertRefsAsNljson() , or insertRefsAsSubtree() — mixable in any order.
" nomen: "Mixed output"] Return_nothing [z: 1.1875 @html: "
Return nothing
•  Omit — the extruction stays transparent (no
output, children promoted as if the
extruction didn't exist).
•  Return — the extruction is removed and its
children are suppressed (dropped entirely, not promoted).
" nomen: "Return nothing"] State_still_via__mdtState_ [z: 1.1875 @html: "
State still via
The mdtState object is mutated directly through
property assignment, not through
helpers:
 ## ${init} \\`\\`\\`javascript
mdtState.counter = 0 \\`\\`\\` ## ${count}
\\`\\`\\`javascript mdtState.counter++
return inject(String(mdtState.counter))
\\`\\`\\` 

" nomen: "State still via `mdtState`"] Adapters____search____searchVotes____votesAsRefs_ [z: 1.1875 @html: "
Adapters —
Adapters are not commands. They are async functions
injected into the eval context by createAdapters() ( adapters.js ) and used toobtainitems, which the insert* verbs then render. All three are await -ed.
AdapterInputReturns
 search(query) glass-search stringref items ( fragments , files , …)
 searchVotes(query)  { campaign, repo? } vote rows from v_voting_campaign 
 votesAsRefs(votes) vote rowsref items
 searchVotes queries the v_voting_campaign view. repo defaults to STATE.repoName . campaign accepts '*' (all campaigns), a prefix, or an array
of prefixes — matching is by prefix, not exact name :
 campaign SQL condition
 '*'  1 — no filter
 'do'  campaign GLOB 'do:*' 
 【'a', 'b'】  ( campaign GLOB 'a:*' OR campaign
GLOB 'b:*' ) 
 【】 none — returns 【】 without querying
This mirrors campaignPrefix in tagCloudByVotingsFromView() . A consequence worth remembering: an
exact campaign name matches only if
something sits below it, so pass the
parent prefix rather than the full
campaign.Rows come back as objects:
 repo campaign nomen aliasRef id
num1 voteCount maxCount rn 

 score is not selected — the deployed view may have
been generated with withScore: false , and its LN() also needs a SQLite built with SQLITE_ENABLE_MATH_FUNCTIONS . It is computed locally instead, from voteCount / maxCount , and added to each row:
 1 +
Math.round(Math.log1p((voteCount /
maxCount) * 100)); 

Verified identical to the view's SQL
expression across the real vote rows. votesAsRefs is a pure conversion — vote rows carry aliasRef , id and num1 , which is everything a ref item needs.
It builds uri the same way a fragments search does ( #/paper/${aliasRef} , falling back to legacyPaperUrl ), sets nomen for the label, and derives fn by stripping the :NNNN node-seq suffix off id so buildRefId() resolves. Vote data ( campaign , voteCount , maxCount , score , rn ) rides along, so insertRefsAsNljson can surface counts without a second
query.It is async despite doing no I/O today — the
signature is the contract, so a later
version can enrich from the DB without
breaking callers. Example — list voted fragments:
 ## ${init} \\`\\`\\`javascript
mdtState.queryVotes = { campaign: '*' }
mdtState.votes = await
searchVotes(mdtState.queryVotes) \\`\\`\\`
### ${list} \\`\\`\\`javascript return 【
insertRefsAsList(await
votesAsRefs(mdtState.votes)), 】
\\`\\`\\` 

Both are wired in adapters.js exactly as search is, so anything that builds a runner
context gets them for free.
" nomen: "Adapters — `search`, `searchVotes`, `votesAsRefs`"] Command_contract___all_verbs [z: 1.1875 @html: "
Command contract — all verbs
HelperInputFragmentsBody
 insert(x, opts?) anything1array→ \\n -joined, object→JSON, else String() 
 inject(s)  string 1raw passthrough, no heading, empty trail
 insertNljson(x, opts?) collection1 ```nljson fence, one JSON per line
 insertRefsAsList(items,
opts?) 
ref items1 - 【nomen】(uri) {data} bullet list
 insertRefsAsNljson(items,
optsOrFn?) 
ref items1 ```nljson fence, scalar cells, auto link 
 insertRefsAsSubtree(items,
opts?) 
ref items N (one per item)heading-only; body fetched lazily in expand() 
 buildUrl(content, mimeType?) is a helper, not a command — it returns
a data: URI string for use inside any of the
above. [object Object] Every other verb yields exactly one leaf
Fragment ( hasChildren: false , inert expand() ) whose heading is an invisible HTML
comment. insertRefsAsSubtree fans out to one Fragmentper item, each with a real visible heading, hasChildren: true , and a real expand() that calls loadRefBody — so the content fetch is deferred until
the render pipeline walks into that
subtree. It also dedupes colliding
trails with -2 / -3 suffixes. [object Object] (conversion-tree provenance) rides on insert , insertNljson , insertRefsAsList , and insertRefsAsNljson . inject never carries it; insertRefsAsSubtree derives sourceFragment itself from buildRefId(item) . Two dispatch sites handle these: processExtructionResult yields real Fragments, while the array
walker in resolveChildTree stringifies commands into a parent's children text. insertRefsAsSubtree is deliberately absent from the second —
nested inside a children resolution there is no lazy expansion in
a flat string context, so it contributes
nothing there.Under the hood every helper produces a
command object ( { insert: 【...】 } / { inject: "..." } / …) that the runner processes. The
extruction must return an array 【cmd1, cmd2, ...】 to yield fragments. A bare non-array
object yields nothing — only undefined or an array is valid. Example — injecting a preamble:
 ## ${notice} \\`\\`\\`javascript
return inject("> **Note:** this
document is generated from live
data.") \\`\\`\\` 

This produces a Fragment whose toString() is just the blockquote — no heading
comment wrapping it. The consumer sees
clean markdown without synthetic HTML
comments. Implementation notes:
•  buildInjectFragment(injectValue) in mdt.js creates the Fragment with body =
normalizeFragmentBody(injectValue) 
— same serialization as buildInsertFragment (array→joined, object→JSON,
primitive→String).
•  normalizeFragmentBody() is the shared helper used by both
protocols, extracted during the inject
implementation.
•  processExtructionResult() (the async generator in mdt.js ) iterates each command in the array and
yields a Fragment per command — insert and inject can be mixed in any order.
• Non-array results are silently ignored
(yield nothing). Only undefined (skip) or 【cmd, ...】 (yield) are valid return values.
•  inject fragments have hasChildren: false and expand() returns an empty async generator — they
are always leaf nodes.
" nomen: "Command contract — all verbs"] hasChildren___extruction_evaluation [z: 2.375 @html: "
hasChildren & extruction evaluation
When evalFn is active, any extruction child heading
causes the parent's hasChildren to be true , since the extruction might produce an insert . This ensures rebuildMd() -style collectors expand to find
evaluated content. Extructions that
evaluate to undefined yield no children (the expansion returns
empty immediately).
" nomen: "hasChildren & extruction evaluation"] Error_behavior [z: 2.375 @html: "
Error behavior
•  No evalFn — extruction bodies are inert (silently
dropped).
•  evalFn provided, body has JS syntax error SyntaxError propagates.
•  evalFn provided, runtime error — error propagates from the evaluation.
The snapshot test "syntax error in extruction
body" 
documents the current behavior without evalFn (silently dropped). When evalFn is added to that test, it should throw.
" nomen: "Error behavior"] buildInsertFragment_serialization [z: 2.375 @html: "
buildInsertFragment serialization
 buildInsertFragment(insertValue,
...) 
handles the { insert } value:
•  Array — mapped item-by-item (objects JSON.stringify , primitives String ), joined with "\\n" 
•  Object (non-array) JSON.stringify 
•  Primitive String() 
This prevents 【object Object】 output when extruction bodies return
arrays or objects (e.g. search results).
" nomen: "buildInsertFragment serialization"] Probes [z: 2.375 @html: "
Probes
Two console.log probes are placed at the extruction
result handling points:
•  probe:mdt-ext-result — in expandChildren() , fires after evalFn returns for a
non-root extruction. Logs { heading, result, hasInsert
.
•  probe:mdt-ext-root-result — in the root iterator, same shape for
root-level extructions.
These are the frontend equivalent of the
backend probe pattern ( PROXY.remoteState?.log({ label
}) 
). The MDT library is a pure frontend
module without PROXY access, so console.log is used directly.
" nomen: "Probes"] Search_Adapter [z: 4.75 @html: "
Search Adapter
The MDT library provides a search
adapter that wraps the app's glassSearchRun() with proper async completion detection,
emitting per-source events and a final allCompletedDone event.
" nomen: "Search Adapter"] glassSearchRunAsync [z: 2.375 @html: "
glassSearchRunAsync
 mdt/glass-search-run.js exports an async wrapper around the
app's glassSearchRun() :
 glassSearchRunAsync(queryString,
ssss, state, STATE, route,
prevHashRoute, proxy) → {
onSource(fn), onComplete(fn),
then(resolve, reject) } 

The wrapper:
• Passes a mock menuInput to glassSearchRun (the autocomplete instance is irrelevant
for programmatic use)
• Wraps proxy.addResultItems to emit source events — each call to addResultItems fires onSource(items) with the incoming results
• Detects completion via a 50ms batch
timer after the last addResultItems call, then fires onComplete(allResults) 
• Handles sync-only sources (files/map) by
resolving on the next microtick via setTimeout(0) 
• Has a 5-second safety fallback for async
sources
Returns a thenable object — supports both event-based and
Promise-based usage:
 // Event-based const search =
glassSearchRunAsync( query, ssss,
state, STATE, route,
prevHashRoute, proxy, );
search.onSource((items) =>
console.log("received",
items.length, "results"));
search.onComplete((allResults) =>
console.log("all done",
allResults.length)); // Promise-based
const allResults = await
glassSearchRunAsync( query, ssss,
state, STATE, route,
prevHashRoute, proxy, ); 

" nomen: "glassSearchRunAsync"] search___adapter [z: 2.375 @html: "
search adapter
 mdt/search-adapter.js exports a thin convenience function:
 search(query, ssss, state, STATE,
route, prevHashRoute, proxy) →
thenable 

Returns empty results for
empty/whitespace queries. Otherwise
delegates to glassSearchRunAsync .
" nomen: "search adapter"] Completion_detection [z: 2.375 @html: "
Completion detection
The "tiny issue" with glassSearchRun() is that it returns synchronously but
kicks off async SQLite fragment searches
(debounced at 5ms). The result list ( resultList from glass-search.js ) is populated incrementally:
•  Sync sources (files, map) push directly to resultList inside searchInRepoJson 
•  Debounced SQLite sources (fragments, nodes, maps, content, links)
arrive later: searchInFragments  proxy.addResultItems  resultList is updated + menuInput.rerender() is called
•  History source arrives via searchInHistory  proxy.addResultItems 
The wrapper intercepts proxy.addResultItems to know when async results arrive. A
50ms batch window absorbs cascaded
calls, then onComplete fires with the full, deduplicated result
list.
" nomen: "Completion detection"] Adapter_Pattern [z: 4.75 @html: "
Adapter Pattern
Adapters are functions injected into the runner context that extruction bodies can call as if
they were local variables. The mechanism
is simple:
• The runner receives context = { search, fetchDb, ...
— keys are names, values are functions
or data
•  evalBody() uses new
AsyncFunction(...Object.keys(context),
bodyText) 
— each context key becomes a named
parameter of the compiled function
• The extruction body can await adapterName(...) just like any JS function

 runner(context, { evalFn: evalBody
}) // ^— keys here become
parameter names in extruction
bodies 

" nomen: "Adapter Pattern"] How_it_works [z: 2.375 @html: "
How it works
Given this setup:
 const doc = runner( { search:
mySearchFn, getUser: myGetUserFn }, {
evalFn: evalBody }, ); 

An extruction body like:
 ## ${find stuff} \\`\\`\\`javascript
const results = await
search("mdd") return insert(
results.map(r =>
r.name).join("\\n"))
\\`\\`\\` 

...is compiled to something like AsyncFunction(search, getUser,
bodyText) 
, so search and getUser are directly accessible in the body
without any import.
" nomen: "How it works"] Naming_rules [z: 2.375 @html: "
Naming rules
• Keys must be valid JS identifiers (no hyphens, no leading digits)
• Use camelCase — this is idiomatic for JS function
names
• Avoid the _mdt_ prefix — that's reserved for
library-injected names (currently only _mdt_label )
• Names that collide with JavaScript
reserved words ( class , return , await ) will break — if you need one, alias
it: { searchClass: ..., ... } 
" nomen: "Naming rules"] Return_protocol [z: 2.375 @html: "
Return protocol
Adapters can return anything — there's
no adapter-specific protocol. The
extruction body is responsible for
handling the return value and deciding
what to do with it via the insert protocol:
•  return insert(value) — the extruction produces output
•  return undefined or no return — extruction stays
transparent
•  throw error — propagates to the consumer (or caught
by onExtructionError )
This means adapters can return raw data
(arrays, objects, strings) and the
extruction body formats it into
markdown.
" nomen: "Return protocol"] Adapter_conventions [z: 2.375 @html: "
Adapter conventions
•  Async by convention — make adapters async even if they're sync. The extruction
body uses await consistently, and an async adapter that happens to resolve
synchronously is cheaper than a sync
adapter that the body wraps in Promise.resolve() .
•  Error handling — let errors propagate. The extruction
body handles them if needed, or onExtructionError catches globally. Don't silently swallow
errors in the adapter.
•  [object Object] — each extruction has its label
available as _mdt_label . Adapters can receive it explicitly
from the body:

 ## ${search mdd}
\\`\\`\\`javascript return insert( await
search(_mdt_label)) \\`\\`\\` 

This is how the same adapter can be
driven by different extruction labels
without hardcoding the query string.
" nomen: "Adapter conventions"] Example_adapters [z: 4.75 @html: "
Example adapters
" nomen: "Example adapters"] 1__Simple_lookup__sync_ [z: 2.375 @html: "
1. Simple lookup sync

 const repoInfo = { ssss: { stars:
42, description: "The ssss
project" }, mdt: { stars: 12,
description: "Markdown construction
pseudo-code" }, }; const doc =
runner({ repoInfo }, { evalFn: evalBody
}); 


 ## ${repo info} \\`\\`\\`javascript
const r = repoInfo【"ssss"】
return insert( \\`**${r.stars}** stars —
${r.description}\\` ) \\`\\`\\` 

" nomen: "1. Simple lookup sync"] 2__Search_adapter [z: 2.375 @html: "
2. Search adapter
Already documented in#search-adapter⸨#search-adapter⸩. The pattern:
 import { search } from
"./mdt/search-adapter.js";
const doc = runner( { search: (q) =>
search(q, ssss, state, STATE, route,
prevHashRoute, proxy) }, { evalFn:
evalBody }, ); 


 ## ${results} \\`\\`\\`javascript
const items = await
search("mdd") return insert(
items.map(i => \\`-
【\\${i.name}】(${i.uri})\\`).join("\\n"))
\\`\\`\\` 

The key insight: the adapter wraps the
app's async search with completion
detection, but the extruction body just
sees a function it can await .
" nomen: "2. Search adapter"] 3__HTTP_fetch [z: 2.375 @html: "
3. HTTP fetch

 const fetchJson = async (url)
=> { const res = await fetch(url); if
(!res.ok) throw new Error(`fetch ${url}:
${res.status}`); return res.json(); };
const doc = runner( { fetchJson }, {
evalFn: evalBody, onExtructionError:
handleError }, ); 


 ## ${github stats}
\\`\\`\\`javascript const data = await
fetchJson("https:/repo")
return insert(
\\`\\${data.stargazers_count} stars,
\\${data.forks_count} forks\\` )
\\`\\`\\` 

The adapter is a thin wrapper around fetch() with error handling. The extruction body
destructures the response and formats it
as markdown.
" nomen: "3. HTTP fetch"] 4__Database_query [z: 2.375 @html: "
4. Database query

 const queryDb = async (sql) =>
{ const db = await getDatabase(); return
db.exec(sql); }; const doc = runner({
queryDb }, { evalFn: evalBody }); 


 ## ${active users}
\\`\\`\\`javascript const rows = await
queryDb("SELECT name, email FROM
users WHERE active = 1") return
insert( rows.map(r => \\`- \\${r.name}
<\\${r.email}>\\`).join("\\n"))
\\`\\`\\` 

" nomen: "4. Database query"] 5__State_access [z: 2.375 @html: "
5. State access
When the runner context includes the
app's state object, extructions can read
from it directly:
 const doc = runner({ STATE,
currentUser: "bebo" }, {
evalFn: evalBody }); 


 ## ${welcome} \\`\\`\\`javascript
return insert( \\`Hello
**\\${currentUser}**, you have
\\${STATE.notifications.length}
notifications\\` ) \\`\\`\\` 

This is how the app passes its reactive
state into extruction bodies.
" nomen: "5. State access"] 6__Composition___multiple_adapters [z: 2.375 @html: "
6. Composition — multiple adapters
Adapters compose naturally since they're
just JS functions:
 const doc = runner({ repoInfo,
fetchJson, currentUser }, { evalFn:
evalBody }); 


 ## ${dashboard} \\`\\`\\`javascript
const user = currentUser const repos =
await
fetchJson(\\`https:/repos\\`)
const summary = repos.map(r => \\`-
\\${r.name}:
\\${repoInfo【r.name】?.description ||
"unknown"}\\`).join("\\n")
return insert( \\`### \\${user}'s
repos\\n\\n\\${summary}\\` ) \\`\\`\\` 

Here repoInfo is a sync lookup, fetchJson is async, and currentUser is a plain string — all coexist as named
parameters.
" nomen: "6. Composition — multiple adapters"] 7__Using___mdt_label__to_drive_adapters [z: 2.375 @html: "
7. Using
The label (text between ${} ) is injected as _mdt_label automatically. This lets a single
adapter serve multiple extruction
variants:
 ## ${fetch todos}
\\`\\`\\`javascript return insert( await
fetchJson("/api/todos"))
\\`\\`\\` ## ${fetch users}
\\`\\`\\`javascript return insert( await
fetchJson("/api/users") )
\\`\\`\\` 

Without hardcoding the path in each body
— although in this case you'd still need
to map the label to the path. A more
practical use:
 ## ${search mdd} \\`\\`\\`javascript
const items = await search(_mdt_label)
return insert( items.map(i =>
i.uri).join("\\n")) \\`\\`\\` ##
${search js} \\`\\`\\`javascript const
items = await search(_mdt_label) return
insert( items.map(i =>
i.name).join("\\n"))
\\`\\`\\` 

The same search adapter is called with different labels.
" nomen: "7. Using `_mdt_label` to drive adapters"] Key_constraints [z: 2.375 @html: "
Key constraints
ConstraintWhy
Adapter names must be valid JS
identifiers
They become AsyncFunction parameter names
Don't use _mdt_ prefixReserved for library-injected context
keys
Adapters are evaluated fresh on each evalFn callNo caching — each expansion re-evaluates
Return { insert } to produce outputAny other return keeps the extruction
transparent
Context is spread, not just the adapterAll context keys are available — plan
namespace accordingly
" nomen: "Key constraints"] 6__E2E_tests [z: 2.375 @html: "
6. E2E tests
Test the full player-paper.js
integration: .mdt file fetch → compile → run with evalBody
+ adapters → rebuild clean md → render.
" nomen: "6. E2E tests"] Conversion_tree___transclusion_provenance [z: 4.75 @html: "
Conversion tree — transclusion
provenance

When an mdt document transcludes content
from source fragments (via extructions),
the produced fragments have virtual
trail positions in the generated
document. To resolve these back to the
real source fragments, the mdt runner
produces a conversion tree alongside the generated text.
" nomen: "Conversion tree — transclusion provenance"] sourceFragment_field [z: 2.375 @html: "
sourceFragment field
Each Fragment now carries an optional sourceFragment :
 { trail: "a/x", heading:
"## <!-- ... -->", body:
"hello", sourceFragment: null
| { fn: "paper/real.mdd",
refId:
"paper/real.mdd::real/heading"
} } 

•  buildFragment() — regular headings: sourceFragment: null 
•  buildInjectFragment() — injected raw content: sourceFragment: null 
•  buildInsertFragment() — extruction-produced fragments: reads cmd.source 
" nomen: "sourceFragment field"] Extruction_protocol___insert___extended [z: 2.375 @html: "
Extruction protocol — insert extended
 insert() accepts an optional second argument { source } :
 // without source (existing
behavior) return 【insert(children)】; //
with source tag (new) return 【
insert(children, { source: { fn:
"paper/real.mdd", refId:
"paper/real.mdd::real/heading"
}, }), 】; 

The source object flows from the command → buildInsertFragment → Fragment → consumer's conversion tree.
" nomen: "Extruction protocol — insert extended"] Consumer_collects_conversion_tree [z: 2.375 @html: "
Consumer collects conversion tree
The consumer iterates fragments and
builds a Map<trail,
sourceFragment> 
:
 const conversionTree = new Map();
for await (const frag of doc) { if
(frag.sourceFragment) {
conversionTree.set(frag.trail,
frag.sourceFragment); } } 

" nomen: "Consumer collects conversion tree"] Rendering_uses_conversion_tree [z: 2.375 @html: "
Rendering uses conversion tree
 renderFractalCollageOfPaper accepts { conversionTree } in opts. In renderAfterEffect , the rendering trail (semicolons) is
converted to / -separated key and looked up in the
tree. If found, the source refId is used as data-fragmentRef instead of the computed virtual refId.
" nomen: "Rendering uses conversion tree"] Trail_format_conversion [z: 2.375 @html: "
Trail format conversion
ContextFormatExample
mdt Fragment.trail / -separated "a/x" 
rendering data-trail ; -separated "a;x" 
conversionTree key / -separated "a/x" 
buildFragmentRef input ; -separated buildFragmentRef(base,
"a;x", sanitize) 
" nomen: "Trail format conversion"] Changed_files [z: 2.375 @html: "
Changed files
•  mdt/mdt.js — insert() helper,
buildInsertFragment/buildInjectFragment/buildFragment,
processExtructionResult
•  player/player-paper.js — .mdt case collects conversionTree
during fragment walk, passes to
renderFractalCollageOfPaper
•  player/player-utils.js — renderFractalCollageOfPaper accepts
conversionTree, resolves source refId
•  mdt/mdt.test.mjs — 5 new tests: sourceFragment
presence/absence, conversionTree
collection

  
" nomen: "Changed files"] }