Unsterwerx

Reconstruction Templates

When you run unsterwerx reconstruct, the canonical content stored in the Universal Data Set is rendered through a Tera template before being written to disk. You can swap the default template for your own to control headers, footers, frontmatter, and overall document layout.

How it works

  1. Unsterwerx resolves the document's temporal state (latest version, or a specific point-in-time if --at is used).
  2. Canonical content is read from the content-addressable store.
  3. The template engine loads templates from {DATA_DIR}/templates/.
  4. A template named report.md is rendered with the document's metadata as context variables.
  5. The rendered output is either written directly (markdown) or converted to an encrypted PDF.

If no custom report.md exists in the templates directory, a built-in default is used.

Template directory

Templates live in:

~/.unsterwerx/templates/

Or under a custom data directory if you use --data-dir:

/path/to/data/templates/

This directory is created automatically during initialization. Drop a .md file there and it becomes available to the renderer.

Available variables

Every template receives these context variables:

VariableTypeDescription
titlestringDocument filename
document_idstringUUID of the document
versionintegerCanonical version number
content_hashstringSHA content hash
is_signedbooleanWhether the document carries a digital signature
contentstringThe full canonical content (denormalized from the Universal Data Set)
generated_atstringISO 8601 timestamp of when reconstruction ran
app_versionstringCurrent Unsterwerx version

Writing a custom template

Templates use Tera syntax, which looks like Jinja2. Variables go in {{ double_braces }}, control flow in {% block tags %}.

Here is a minimal custom template:

markdown
# {{ title }}

{{ content }}

---
Reconstructed from document {{ document_id }} (v{{ version }}) on {{ generated_at }}.

Save this as ~/.unsterwerx/templates/report.md and every future reconstruct call will use it.

Conditional blocks

Use {% if %} to handle signed documents differently:

markdown
---
title: {{ title }}
document_id: {{ document_id }}
version: {{ version }}
generated_at: {{ generated_at }}
{% if is_signed %}signature_status: preserved{% endif %}
---

# {{ title }}

{{ content }}

{% if is_signed %}
> This document carries a digital signature. The original signature state has been preserved.
{% endif %}

---
*Reconstructed by unsterwerx v{{ app_version }} at {{ generated_at }}*

Frontmatter

YAML frontmatter at the top of a template is passed through to the markdown output, but stripped automatically when generating PDF. You can put whatever metadata you need there.

Built-in templates

Three templates ship with Unsterwerx and serve as starting points:

TemplatePurpose
report.mdGeneral-purpose reconstruction with frontmatter and signature handling
contract.mdContract-style layout with document ID footer
invoice.mdInvoice-style layout with document ID footer

The renderer always looks for report.md. The contract and invoice templates exist as reference examples you can copy and adapt. To use one of them as your default, rename it to report.md in your templates directory.

Output formats

The reconstruct command produces two formats:

Markdown

Writes the rendered template output directly. What you see in the template is what you get in the file.

PDF

The rendered markdown is converted to PDF with these characteristics:

Format is auto-detected from the output file extension (.md or .pdf) or forced with --format.

Signed documents

When reconstructing a signed PDF, Unsterwerx returns the original preserved PDF file rather than re-rendering through the template. This preserves the cryptographic signature chain. The template is bypassed entirely in this case.

Tips