Contributing to Thuishaven

Thuishaven is a curated playbook, not an open catalog. Every pattern is opinionated by design: one recommended app, one deploy target, one exposure model. That only works if contributions are held to a clear bar. This document explains that bar and the process.

What makes a good pattern

A pattern solves a use case, not “how to install app X”. Good: “Date picker for sharing with friends”. Bad: “Rallly installation guide”. The app is the recommendation, not the subject.

A pattern must:

Make it executable, not just readable

A pattern is followed by agents as well as humans. Three optional frontmatter fields turn prose into a machine-checkable contract — use them wherever the work is genuinely scriptable, and keep prose for the GUI-bound steps that aren’t:

The validator enforces uniqueness of input names and assertion ids, the check-XOR-manual rule, and that every ${INPUT} an assertion references is a declared input. Aim for at least one scriptable assertion per pattern.

The declaration: you ran it

Every pattern PR — new pattern or substantive change — must include this declaration in the PR description:

I have personally run this pattern end-to-end on a real server, following the steps as written, and it produced a working result.

This is not a formality. The whole value of Thuishaven over a generic LLM answer is that a human verified the recipe. If you wrote the steps from documentation knowledge without running them, say so explicitly — the pattern can still land as experimental, but the review will be stricter and the status stays experimental until someone validates it.

Pattern lifecycle: experimental → stable → deprecated

When an app’s recommended setup changes in a breaking way, bump version in the frontmatter. We keep only the latest version in the repo; Git history is the archive.

How to submit a pattern

  1. Fork the repo and create a branch.
  2. Copy the frontmatter structure from an existing pattern in patterns/. The core fields are required; inputs, assertions, and tested_against are optional but expected wherever the pattern has scriptable parts. All of it is validated against schema/pattern.schema.json.
  3. Name the file patterns/<id>.md where <id> equals the id field (kebab-case).
  4. Follow the body structure convention: Context → Decisions explained → Step-by-step → Verification → Gotchas → Maintenance notes. Where you declared inputs/assertions, surface them in the body too — a script that generates the env from the inputs, and a verify.sh that runs the scriptable assertions.
  5. Set status: experimental — all new patterns start there.
  6. Validate locally: npm install && npx tsx scripts/validate-patterns.ts.
  7. Open a PR. The template asks for the run-it-yourself declaration and your reasoning on alternatives.

New categories can be proposed via PR against the schema, with justification.

How reviews work (maintainer-review model)

Every PR is reviewed by a maintainer before merge — currently that’s @hiddevh. CI catches mechanical errors (schema violations, broken related-pattern references) before a human looks at it; the human review is about judgment: Is the recommendation sound? Are the alternatives fairly considered? Are the steps complete and honest about gotchas?

Expect questions about why you chose the app, not just how to install it. Recommendation criteria we apply:

The maintainer-review model is intentional while the project is small. If sustained, trusted contributors emerge, co-maintainership follows naturally.

Non-pattern contributions

Fixes to tooling, schema, CI, or docs follow the normal PR flow without the run-it-declaration. Keep commits in Conventional Commits format (feat:, fix:, docs:, chore:…).

Ground rules