coulomb-social/docs/architecture/transclusion-and-chunks.md
tegwick 64d4dcda7c Note page-first content with markitect transclusion as chunk model
Document markitect include/selector/region/explode primitives and map Bubble
chunks to addressable extractions rather than a priori chunk storage.
2026-08-12 23:48:25 +02:00

7.3 KiB
Raw Blame History

Transclusion vs a priori chunks — coulomb + markitect

Field Value
Date 2026-08-12
Status design note (aligns with ArchitectureBlueprint + existing Bubble map)
Layer markitect-tool (syntax) · coulomb product model

Thesis

Pages of markdown are the fluent unit of knowledge work.
A “chunk” should usually mean an addressable region or extracted view of a page (or of another page), not a separate first-class storage object that documents are assembled from a priori.

Bubbles custom.chunk graph (stages, subchunks, backlog) is powerful but tool-shaped: it forces structure before fluency. Rebuild should invert that:

Write fluently in a page
  → address regions when reuse is needed
  → transclude / extract / promote
  → only then materialize a derived page or asset if it earns independence

Tooling adapts; it does not demand an ontology of chunks up front.


What markitect-tool already provides

1. Include / transclusion (FR-022)

Documented in markitect-tool/docs/transform-compose-include.md.

Markers:

<!-- mkt:include path="sections/intro.md" -->

<!-- mkt:include path="other.md" selector="sections[heading=Summary]" heading_delta="1" -->

{{include:sections/intro.md}}
Attribute Role
path Target markdown file (relative; sandboxed under base dir)
selector Optional query — only matching content is included
heading_delta Shift heading levels on include
include_frontmatter Optionally keep target frontmatter

API: resolve_includes(...)
Safety: cycle detection, max depth, no path escape, markers inside fences left literal
Provenance: include events record marker line, target path, selector, heading shift

This is transclusion without a database: the including page remains editable markdown; resolution is a deterministic operation for render/export/agents.

2. Selectors (query / extract)

docs/query-extraction.md — extract sections/blocks without inventing chunk rows:

sections[heading=Context]
sections[heading~=risk]
sections[contains~=PROBLEM]
blocks[type=paragraph]
headings[level=2]

mkt transform --extract SELECTOR can replace a document with extracted content — promote a region to a standalone body when needed.

3. Content references (addressable units)

docs/content-references.md — name units without a priori chunk types:

path/to/file.md
path/to/file.md#section:introduction
path/to/file.md::sections[heading=Decision]
std:clauses/payment.md#region:boilerplate

Named regions (in-document, optional):

<!-- mkt:region id="boilerplate" tags="legal reuse" -->
Reusable text.
<!-- /mkt:region -->

Units carry unit_id, kind (document | section | heading | …), source span, content hash — enough for cache, ACLs later, and include targets.

4. Explode / implode (optional materialization)

docs/explode-implode.md — temporarily split a large page into section files + manifest, edit, reassemble.
Not “documents are made of chunk types”; it is a reversible workflow when humans want filesystem granularity.

5. Compose

compose_files — concatenate whole files (different from selective transclusion).


Mapping to coulomb / Bubble concepts

Bubble (live) Page-first + transclusion model
custom.page SoR page — frontmatter + body + backmatter
custom.chunk as storage atoms Avoid a priori — use sections/regions/selectors inside the page
Chunk list / SelectedChunk Derived view: query sections[...] or region index on the page
Subchunks Nested headings / nested regions, not separate types
Copy page Duplicate page file (or deep-copy with rewritten includes)
Transfer page Move/re-home page file; includes keep relative or get rewritten
Card UI Projection of page (title, abstractor, visual) — may also project a transcluded excerpt as card body
Article + chunks_list Page that includes other pages or regions, or a view over query results
Stage1…Stage5 on chunks Optional workflow metadata on regions/frontmatter later — not required for S1

“Extract a chunk out of a page”

Three elegant operations, increasing commitment:

Op Meaning Storage impact
Address Point at page.md#section:foo or ::sections[heading=Foo] None — still one page
Transclude Another page includes that region via mkt:include + selector Still one SoR for the region; host page has a marker
Promote / extract Write region to pages/foo-excerpt.md (transform extract or explode entry) New page; optional leave include behind in origin

Fluency prefers address → transclude → promote, not create chunk type first.


Product rules (proposed)

  1. SoR is the page file (markdown). No required Chunk table for stage 1.
  2. Cards show page projections; optional card body = first section or selected region.
  3. Reuse uses markitect include/reference, resolved at render/export/agent time (and optionally cached).
  4. Independent editing of a reused piece = promote to its own page, then transclude from both places.
  5. DB/cache may index section titles and region ids for search/cards — disposable, rebuilt from markdown.
  6. Bubble chunk migration: prefer serialize chunk trees into page sections/regions or separate pages with includes, not recreate custom.chunk as a permanent model.

Where this sits in the architecture

coulomb UI (cards, edit, copy, transfer)
        │
        ▼
PageOps (get/put page markdown)
        │
        ├─ markitect-tool: parse, query, resolve_includes, extract, references
        └─ content plane: store page files (+ assets)

Transclusion is a syntax-layer concern (markitect-tool), not a reason to pick kontextual vs shard-wiki. Any content plane that stores markdown files can host includes.


Gaps / future (markitect-tool)

From markitect docs themselves (not blockers for S1):

  • Variable / conditional transclusion not yet
  • Includes currently path-first; content-reference-as-include path is designed for later
  • Dependency graph invalidation for caches is planned (WP-0007 hooks)

Coulomb can start with path + selector includes and section/region addressing.


Relation to stage-1 cut

Stage-1 need Transclusion stance
Title / Abstractor / Visual Page frontmatter
Page CRUD Whole page files
Page copy File duplicate; resolve or rewrite includes
Page transfer Move file between spaces; rewrite relative includes
Chunk UX (if users need “pieces”) Address/transclude first; promote only if sticky

One-liner

Dont model knowledge as Lego chunks that assemble into pages.
Model pages as living markdown, and treat chunks as addressable, transcludable extractions that tooling materializes only when reuse demands it.

  • markitect-tool: docs/transform-compose-include.md, docs/content-references.md, docs/query-extraction.md, docs/explode-implode.md
  • coulomb: docs/architecture/ArchitectureBlueprint.md, docs/capability/existing-bubble-capability-map.md