Highly experimental. WeaveMark’s notation, Processor, examples, and public interfaces are still evolving — expect rough edges, surprising results, and breaking changes.

Hands-on tutorial

Reuse & refine: one library, many outputs.

This is the promplet superpower. A promplet is not an isolated prompt: it refines reusable building blocks with @refine, and the same blocks can compile into completely different artifacts. In this lesson two real specs pull in the same finance fragments — one produces a decision analysis, the other a local-first dashboard specification.

You compare Two checked-in specs that share the same finance fragments.
You produce A decision-analysis prompt and a build-ready app specification.
The big idea Update a concept once; every promplet that refines it picks up the new guidance on its next compile.

In the repository

Source and folder links open GitHub. Commands assume the repository-root setup from Tutorial 1.

The copy-paste problem

Most prompt libraries are folders of text you copy and paste. The moment you paste a checklist into two prompts, it has forked: fix a flaw in one copy and the other still carries it. Prompts drift, and hard-won guidance rots.

WeaveMark replaces copy-paste with refinement. A reusable fragment lives in exactly one file. Any promplet pulls it in with @refine, and the compiler weaves it into that specific document. Update the fragment once and every promplet that refines it picks up the new guidance on its next compile — without editing them. Since compilation is model-based, the quality of each result remains model- and run-dependent.

Refinement, not inclusion. @refine does not paste the file in. It obliges the compiled result to satisfy the imported spec while reading as one coherent document for this task.

The shared building blocks

Two fragments in the library capture how passive income actually works. They are pure domain knowledge — no product, no audience baked in:

  • passive-income-capital-growth — the planning frame: passive-income sources, the capital base, and safe-to-spend amounts versus principal drawdown.
  • passive-income-forecasting — the method: forecast spendable monthly income from explicit sources, schedules, taxes, and reserves without turning growth into erosion.

Neither fragment knows whether it will end up in an essay, a checklist, or an app. That is the point. Now watch two very different specs put them to work.

Output A — a decision analysis

The first spec is an analysis promplet. It refines reasoning and finance guidance, decision lenses, and the two finance fragments, then frames a concrete household question.

@promplet version: 0.7

@refine module:weavemark.std.reasoning.base_analyst
@refine module:weavemark.domains.finance.finance_safety mingle: true
<!-- ... plus evidence-quality, strategic-problem-analysis, and resilience lenses ... -->
@refine module:weavemark.domains.finance.passive_income_capital_growth
@refine module:weavemark.domains.finance.passive_income_forecasting
@refine module:weavemark.std.lenses.decision_gate mingle: true

# Financial independence passive-income decision

@{person_name} is deciding whether their household has enough financial
resilience to reduce dependence on a high-pressure job ...

From financial-independence-decision.weavemark.md.

The full decision promplet asks for a realistic household snapshot. Save these example values as outputs/reuse/decision-vars.json, then compile it into a pastable analysis prompt:

mkdir -p outputs/reuse
cat > outputs/reuse/decision-vars.json <<'JSON'
{
  "person_name": "Alex",
  "age": "42",
  "invested_assets": "$1.4M",
  "annual_income": "$240k",
  "annual_spending": "$95k",
  "annual_investments": "$60k",
  "target_spending": "$70k",
  "emergency_fund": "12 months",
  "real_return": "4%",
  "reduced_hours_income": "$120k/year",
  "lower_pressure_income": "$90k/year",
  "expected_monthly_passive_income": "$4,500",
  "confirmed_monthly_passive_income": "$3,200",
  "monthly_reinvestment_target": "$1,500",
  "monthly_tax_reserve": "$800",
  "principal_drawdown_preference": "Avoid principal drawdown"
}
JSON
weavemark library builtin:catalog/standalone/financial-independence-decision \
  --batch-only \
  --vars-file outputs/reuse/decision-vars.json \
  --output outputs/reuse/decision.md
What you get: a prompt that treats the situation as a strategic decision — distinguishing confirmed from projected income and safe-to-spend from reinvestment — because the finance fragments made those distinctions obligations.

Output B — an app specification

The second spec is a software promplet. It refines an a local-first web stack, durable SQLite storage, a dashboard module, and the same two finance fragments.

@promplet version: 0.7

@refine module:weavemark.domains.programming.stacks.typescript_nextjs_prisma_sqlite
@refine module:weavemark.domains.programming.types.local_first_webapp
@refine module:weavemark.domains.programming.modules.dashboard
@refine module:weavemark.domains.finance.passive_income_capital_growth
@refine module:weavemark.domains.finance.passive_income_forecasting

# Passive-Income Planning Dashboard

Design @{app_name}, a local-first web application for people pursuing financial
independence through passive income and disciplined capital growth ...

From passive-income-planning-dashboard.weavemark.md.

weavemark library builtin:catalog/standalone/passive-income-planning-dashboard \
  --batch-only \
  --var app_name=Fathom \
  --output outputs/reuse/app-spec.md
What you get: a build-ready specification whose financial modules — safe-to-spend, forecasting, capital-erosion warnings — are induced by the finance fragments rather than reinvented by hand. In Spec to app you hand a spec like this to a programming agent and get a running app.

Same blocks, different artifacts

Look at the two @refine headers side by side. The two finance lines are identical. Everything downstream diverges:

Decision analysis App specification
Shared blocks passive-income-capital-growth + passive-income-forecasting
Plus reasoning, finance guidelines, decision lenses local-first web stack, SQLite storage, dashboard module
Compiles into a decision-analysis prompt a build-ready software specification
Next step paste into an assistant for the analysis hand to a programming agent (Spec to app)

Improve passive-income-forecasting once — sharpen a tax assumption, add a reserve rule — and both the decision prompt and the app spec get better the next time they compile. That is reuse that does not rot.

Blend or preserve: mingle

You may have noticed some @refine lines carry mingle: true and some omit it. Those forms are equivalent: mingle: true is the default. Use explicit mingle: false only when imported wording and structure must remain visibly layered.

  • @refine passive-income-forecasting.weavemark.md or @refine passive-income-forecasting.weavemark.md mingle: true — semantically blends the imported obligations into one coherent host document.
  • @refine passive-income-forecasting.weavemark.md mingle: false — performs a preservation-oriented structural merge, keeping imported wording and sections recognizable as a layer. This form cannot carry an indented refinement body.
Rule of thumb: accept the default blend for normal specification refinement. Choose mingle: false only when source wording or section boundaries must stay visible in the result.

Final step: Use the output

The two compiled files have different jobs, so do not treat them as interchangeable Markdown notes.

What to do with the output: paste outputs/reuse/decision.md into ChatGPT, Claude, Gemini, Copilot Chat, or another assistant to get the household decision analysis. Give outputs/reuse/app-spec.md to a programming agent or to weavemark implement; it is a build specification, not something that executes by itself.

What you learned

  • Reusable knowledge lives in one fragment, not in copies.
  • @refine obliges a spec to satisfy an imported one, woven into a single document.
  • The same fragments compile into radically different artifacts.
  • Updating a fragment propagates its new guidance to every promplet that refines it on the next compile.
  • Plain @refine defaults to mingle: true; explicit mingle: false preserves and layers imported wording.
Next: put refinement to work in a domain that must adapt to the reader in Adaptive tutor.