MEJE PROCESS · MEJE Librarying Workflow (21 chapters)
Chapter 7. Building the Skeleton: How a CSV Becomes Obsidian Files
Chapter 7. Building the Skeleton: How a CSV Becomes Obsidian Files
The 13-column CSV may hold 1,000 to 2,000 headwords in neat rows, but that table is not yet a collection of files. Nothing appears in Obsidian: there is no graph view, the sidebar file list is empty, and the IP’s vocabulary remains inside a single spreadsheet.
The third-stage skeleton build turns that table into individual files. One row becomes one file; only when this stage is over does the Vault finally unfold across the screen.
Separating structure from content: an old principle
Before a book goes to press, an editor marks its margins in red: “this title in 14-point Gothic,” “this paragraph without an indent,” “this quotation in italics.” Those marks describe structure, not content. The author’s wording remains intact; only the way it will be arranged and displayed is recorded separately.
This is the separation of structure and content: design must be changeable without altering the content itself. The same manuscript should be printable as a different-sized paperback. With computers, the principle became clearer still. HTML and CSS divide this work: HTML says “this is a title; this is a paragraph,” while CSS decides their size, color, and spacing. Apply another CSS sheet to the same HTML and the visual result changes completely. Databases work similarly: a schema defines the available fields, while data supplies their actual values.
Wikipedia’s infobox is a familiar example. Open any biography and the top-right box places birth date, nationality, occupation, and spouse in the same positions. A single person-infobox template determines the structure; each article merely fills it with its own data. A small adjustment to that template reaches tens of thousands of pages at once because structure and content have been separated.
Librarying’s third-stage skeleton build applies this principle to Obsidian files. The frontmatter at the top of a Markdown (.md) file carries the structure, and the text below carries the content. They remain clearly distinct and perform different jobs.
What “deterministic transformation” means
In Chapter 3, we called the third-stage skeleton build “deterministic automation.” First-pass extraction has an AI work partner read documents and draw out keywords, so extracting the same document again can yield slightly different results. Second-pass consolidation can also produce a slightly different grouping when it revisits synonym candidates. Both stages contain AI’s probabilistic variation.
The third-stage skeleton build is different. Its rules for converting a 13-column CSV into Markdown files are explicit. Which column enters which frontmatter field and which column occupies which position in the body are fixed from the outset. Run the same automation on the same CSV, and it always produces the same result. That is deterministic transformation.
In current practice, this transformation is not treated as merely “running a script,” but as a contract. Its inputs, outputs, execution point, and acceptance conditions are defined beforehand. Immediately after the build, we check that headword-file count matches second-pass CSV row count, that no YAML is broken, that no filenames collide, and that no worldbuilding-axis field is missing. Validation reports arrive as the files are made, not later as an afterthought.
The producer’s role can appear almost absent at this stage. “Appear” matters. In principle, every one of 1,500 automated results should be inspected; in practice, examining every file creates severe inefficiency and a bottleneck. Yet simply accepting automation without attention leaves an unreliable result. We automate the labor-heavy conversion not because humans may disappear from Stage 3, but to preserve their energy for the fourth-stage narrative writing where it is truly needed.
Determinism brings both benefit and risk. With no variation, 1,500 files can be created at once without human hands. But one flaw in a transformation rule gives all 1,500 files the same flaw. A single mistake is replicated 1,500 times. Therefore a person reviews the build once it finishes. Since the defect belongs to the rule rather than an individual file, correct the rule and run the build again to repair all 1,500 files at once. Set sound rules, let automation process them, and have people confirm the result.
Frontmatter, a contract machines can read
Let us examine one Markdown file created by the skeleton build. We will use the headword “Perfumer” from the romance-fantasy world Hyanggung as an example.
---
title: Perfumer
aliases: [Perfume Artisan, Scent Master]
category: Character
worldbuilding_axis: Scent
english: Perfumer
romanization: Johyangsa
version: Current
tags:
- category/Character
- axis/Scent
- version/Current
sources:
- Rulebook, 3rd ed., p.24
related:
- "[[Scent]]"
- "[[High Society]]"
- "[[Anosmic]]"
---
**A perfumer is a craftsperson who blends scents to move people’s emotions and loyalty. In this world, where scent itself is magic, perfumers hold both power and information.**
A perfumer captures and distills [[Scent]] to make alluring and loyalty scents, and designs whose hearts to buy in [[High Society]]. Yet no perfume works before an [[Anosmic]], who is immune to scent.
**Translation**: Perfumer. A perfumer of Hyanggung. This is not an ordinary maker of fragrances but a magical class that manipulates emotion and loyalty through scent; “perfumer” alone can be too narrow. Consider a rendering such as “scent-weaver” or “scent-mage,” or retain the original term alongside it.
%% LLM %%
%% /LLM %%
%% Notes %%
%% /Notes %%
The area at the top, enclosed by ---, is frontmatter. Written in YAML, it is a block people rarely need to read directly; search functions and automation tools read these fields instead.
We call frontmatter “a contract machines can read” for a reason. A person can see the word “Perfumer” and infer from context and experience that it is a character who handles scent. A machine cannot: it must be told explicitly that “this file’s category is Character and its worldbuilding axis is Scent.” Frontmatter performs that task. Search Obsidian for tags such as category/Character or axis/Scent, and the relevant file is selected at once. Future automation built on this Vault will also read frontmatter to understand a file’s nature. The frontmatter we design now is therefore not only for the present job, but a document of promise handed to every future tool working with this IP.
The mapping from second-pass CSV columns to frontmatter fields is one-to-one. The representative keyword becomes title, the alternate names become aliases, the classification becomes one of nine category values, and the IP-specific axis becomes worldbuilding_axis. English name becomes english, romanization becomes romanization, version status becomes version, sources become sources, and related keywords become the wikilink list related. Because this correspondence is unambiguous, the conversion can be fully automated. No human judgment is required.
Metadata, an old promise
Frontmatter is not Librarying’s invention. Fields that have handled digital materials for a long time call information such as title, description, date, format, source, and relations—kept outside the body—metadata. Metadata systems such as Dublin Core ultimately ask basic questions: “What is this resource called?”, “What is it about?”, “When was it made, and what does it relate to?”
Librarying’s frontmatter has the same role. title is the headword’s name, aliases are its alternate names, category and worldbuilding_axis are its type and location, and sources records where it came from. If the body explains what the headword means, frontmatter explains what kind of resource the headword file itself is.
This distinction matters because later tools need not interpret the entire body to read the Vault. Requests such as “collect only mechanisms on the Scent axis,” “find only retired headwords,” or “extract entries sourced from Rulebook 3rd edition” can be handled immediately when frontmatter exists. Strong metadata raises a Vault from a bundle of pleasant-to-read documents to a body of material that can be searched, verified, and reused.
The body’s three layers
Below frontmatter, after ---, comes the body. It has three layers.
Definition is the first bold paragraph. It carries the Definition column from the second-pass CSV in its complete one- or two-sentence form. It is the first sentence seen when another headword file refers to this entry or when an AI work partner reads the file for context. The more carefully this compact statement of a headword’s essence is refined, the better the citation quality of the entire Vault becomes.
Detailed description follows the definition. It contains the Detailed Description column from the second-pass CSV, with related headwords connected as [[links]]. Each link is a strand in the Vault’s network: one [[Scent]] link becomes a connection between the Perfumer and Scent files, shown as a line joining two points in graph view.
Translation note contains the Translation Note column from the second-pass CSV, a letter to a future translator. It records what to watch for when rendering the headword in another language, which terms are already approved, and why a literal translation may be impossible.
Below these layers sit two blocks that are created empty at skeleton-build time: the LLM block and the Notes block.
Why the LLM block is left empty
Why is the block from %% LLM %% to %% /LLM %% empty? It is where narrative will be written in the fourth stage: a 200- to 1,000-character account that unfolds one headword as a continuous piece of writing.
There is a more important reason. The third-stage skeleton build is automation. Automation can establish structure, but it cannot create. Definitions and detailed descriptions are transferred from the second-pass CSV, so automation can process them. The narrative for the LLM block is different: it portrays the headword as something alive within the IP world. The definition “A perfumer is a craftsperson who moves emotions and loyalty through scent” and a narrative about “a perfumer who bought every heart in high society with scent, then met an unfeigned reaction for the first time before an anosmic person untouched by that scent” are fundamentally different. The latter is creative work, performed in Stage 4.
A Vault after Stage 3 is a dictionary. A Vault after fourth-stage narrative writing is a living IP world’s memory repository. The LLM block makes that difference. In Obsidian, %% denotes a comment that does not appear in output; it encloses both the LLM and Notes blocks so that the workspace remains separate from finished output.
Idempotency: safe even when run twice
Idempotency means that running the same operation several times leaves the same result as running it once. Pressing a light switch is not idempotent: one press turns it on, the next turns it off. Setting a light to the on state is idempotent, because doing it again when it is already on changes nothing. In database terms, repeating an INSERT creates two rows and is not idempotent; an UPSERT, which updates if present and adds if absent, leaves one result even when given the same data twice.
Why does idempotency matter in Librarying? An IP changes continuously during operation: new books arrive, established settings are revised, new headwords are added, and the third-stage skeleton build must be run again whenever the second-pass CSV is updated. By then, fourth-stage work may already have written 1,500 narratives in %% LLM %% blocks. Rebuilding the skeleton must not erase them. Losing hundreds of hours of writing in one rebuild would be a disaster.
Librarying’s idempotent update rule solves this. Frontmatter, definitions, detailed descriptions, and translations are overwritten and refreshed from the second-pass CSV on each run. In contrast, the %% LLM %% and %% Notes %% blocks are preserved, leaving untouched both Stage 4 narratives and worker edits.
Suppose the official English name of Perfumer changes from “Perfumer” to “Scent-Weaver.” Update that English-name column in the second-pass CSV and run the skeleton build again. The english field in Perfumer’s frontmatter becomes the new value, while a completed narrative already in the LLM block remains. The same applies when new IP content expands the detailed description of a headword called “After-scent”: refresh the second-pass CSV and rebuild; the description changes, but the LLM block remains intact. This idempotent rule lets the Vault be updated throughout the life of an IP without losing completed creative work.
Stub files: giving aliases their own filenames
The skeleton build produces more than headword files. It also creates stub files.
What happens when someone enters the link [[Perfume Artisan]] in Obsidian? Obsidian seeks a file called Perfume Artisan. The aliases field in frontmatter is also searchable, so if Perfume Artisan is listed as an alias of Perfumer, the search finds the Perfumer file.
There is a trap, however. Obsidian wikilinks work by filename. Aliases work well in search, but a [[link]] from another file must exactly match a filename. If the filename is Perfumer and a user enters [[Perfume Artisan]], Obsidian finds no file of that name, displays it as a not-yet-created file, and cannot draw the connection.
Stub files solve this. Create a file for each alias, and make that file point to the representative headword file.
---
title: Perfume Artisan
redirect: Perfumer
type: stub
tags: [stub]
---
See [[Perfumer]].
Now [[Perfume Artisan]] leads to the Perfume Artisan file, which in turn points to Perfumer, restoring the connection. Wikipedia offers an easy analogy: searching “Kimchi” in English leads to the “Kimchi” article because Kimchi is a redirect page. A stub file is precisely such a redirect page.
If Perfumer has the aliases Perfume Artisan and Scent Master, two stub files are made. It is entirely normal for an IP to have hundreds or thousands of stubs. With 1,500 headwords and one or two aliases apiece, there may be 1,500 to 3,000 stub files. They sit alongside headword files in the same folder, without subfolders, and type: stub distinguishes them so graph view can filter or hide them.
The manifest file: the build’s receipt
Markdown files are not the skeleton build’s only output. It also creates a manifest file summarizing the build result. Named _vault_manifest.json, it sits alongside the Vault folder.
It serves the same purpose as a build manifest in software development. When an application is built, a companion file records which files were made and their sizes and hashes, so a deployment can identify a version’s state at a glance. Librarying’s manifest does the same, but records IP vocabulary statistics rather than file hashes.
The manifest records the project name, Vault path, build time, and source CSV filename. It also records permitted worldbuilding-axis values and headword counts per axis, total headword count and counts for each of the nine categories, counts by version status, and the number of stub files. These are the Vault’s statistics.
Two further items are added. First is progress status: the manifest remembers how far the Vault has moved through Stages 1–4, which batches are complete, and which remain. If fourth-stage writing pauses and resumes the next day, workers begin with pending batches in the manifest instead of relying on memory. Second is handoff status: whether the Vault is ready for the next task to read, whether verification remains, and when it was last handed off.
The manifest also catalogs supporting documents. Character-relationship maps and chronologies are not headword files, but Vault consumers need them; they must be registered from the beginning so verification can ask whether every promised supporting document exists. In the past, such documents were remembered after Stage 4; now they are listed from the skeleton-build stage.
The manifest’s practical value is review. If the second-pass CSV has 1,847 rows, the build must produce 1,847 headword files; open the manifest and confirm it in five seconds. It also makes category-level inspection possible. Only two headwords in Character is a warning sign; only ten headwords on the Scent axis in a scent-centered IP signals incomplete extraction. When fourth-stage narratives are written in multiple rounds, the manifest also shows where to continue.
The manifest has another role: it is a provenance record of the inputs, activities, and reviewers through which this Vault reached its present state. Just as W3C PROV records processes and agents for assessing data trustworthiness, Librarying’s manifest joins source documents, extraction, consolidation, build, verification, and handoff in one line. Source documents, CSVs, and .md files are outputs; extraction, merging, and build are activities; and people, AI work partners, and automation tools are agents participating in those activities.
Seen this way, the manifest is not a mere statistics file. It is an evidence bundle answering, “Can this Vault be trusted now?” It preserves when it was built, which CSV it came from, which verification it passed, and whether it is ready for the next task, so its condition remains knowable even months later.
Meeting the Vault for the first time after the skeleton build
I still remember the moment 1,500 files appeared together in a folder. A moment earlier, the screen contained only one spreadsheet. Run the automation, wait briefly, and the sidebar fills with filenames. Words that had lived in single table cells become files with their own names. The left sidebar lists 1,500 to 2,000 files in Korean alphabetical order. Scroll through names such as “Alluring Scent,” “Windless Valley,” “Anosmic,” “Gate Scent,” “Sealed Scent,” “High Society,” and “After-scent,” and you begin to sense what beings inhabit this IP.
Open one file and its definition and detailed description are present, while its LLM block remains empty. The dictionary’s skeleton has been prepared.
Click graph view and the screen changes at once: 1,500 points and their connecting lines fill it. A point is a headword; a line is a wikilink. The nine categories distinguish them—characters in blue, locations in green, mechanisms in orange. The points attracting unusually many lines are the central headwords: hub candidates.
The first sensation of seeing this graph resembles walking separate city alleys one by one, then viewing their entire map from the sky for the first time. A graph view makes structures visible that individual headwords conceal: which entries sit at the IP’s center or edge, and which categories produced especially many entries. This picture is the third-stage output of Librarying, and it becomes the map for fourth-stage narrative writing. Begin with the points where many lines converge.
What people do in Stage 3
The third-stage skeleton build is almost entirely automated. Even so, people must personally handle three tasks.
Manifest review after the build means checking the numbers: whether second-pass CSV row count exactly matches Markdown-file count, whether any category or worldbuilding axis has a count far from expectation, and whether the number of stub files is reasonable. It takes three to five minutes.
Random sampling of Vault files means choosing ten to twenty files at random from the sidebar and opening them to check that frontmatter is filled correctly, that definitions fit their headwords, and that wikilinks in detailed descriptions are valid. Five minutes is enough. If the sample reveals a problem, either the transformation rule or the second-pass CSV’s data quality is wrong. Find and correct the cause at the rule level, then rebuild. Hand-correcting files one by one is the wrong approach.
Confirm automated verification immediately after the build. A [[link]] in a detailed description whose target file does not exist is a dangling link. Without the target, it points into empty space in Obsidian graph view. Automated checks can detect such link-integrity failures as well as .md file count, frontmatter parsing, filename collisions, and missing worldbuilding_axis fields. Correct these urgent problems as soon as they are discovered. Dangling links usually arise in two ways: a related keyword in the second-pass CSV uses spelling different from the headword’s representative keyword—for example, entering “Anosmian” when the registered term is “Anosmic”—or a related keyword is linked but was never registered as a headword. Standardize the spelling in the first case; consider adding the keyword as a headword in the second.
Once the skeleton is in place
The third-stage skeleton build is the Librarying pipeline stage requiring the least human touch. It needs almost no creative judgment; automation works quietly. When it ends, the Vault takes visible form for the first time.
Chapter 8 examines hubs and leaves. We will consider how to distinguish a central hub from a peripheral leaf among the graph’s points, and why writing should begin by concentrating on hubs.
© 2026 MEJE WORKS Corp. & 김동은WhtDrgon. All rights reserved.