# Contributing to Assemblash Thank you for your interest. Assemblash is a local-first, headless visual document engine for humans and AI agents. This document explains what the project wants from contributions and how you propose one. Please also read the [Code of Conduct](CODE_OF_CONDUCT.md). ## Project status **Released at 1.13.0.** Released binaries support six targets. See [README.md](README.md) for implemented features. See [PRD.md](PRD.md) for the product requirements. `1.0.0` makes the document schema (`schemaVersion` 1) and the operation API stable. A change that breaks either is a MAJOR release and ships a migration. So a pull request that changes the shape of an existing operation, or of a document field, must say so and must give arguments for it. It must not add the change quietly. Additive fields with defaults are the usual way to extend both. ## The one question to ask first > Does this belong in the generic engine, or in a downstream adapter? Assemblash stays deliberately small (PRD §4, "Non-goals"). Product-specific behavior, brand rules, templates, and private workflows belong in adapters or downstream applications. They do not belong in the core. ## What contributions should prioritize - small, composable features; - stable document semantics; - tests for every document operation; - reproducible exports; - explicit security boundaries; - provider-neutral integrations; - documentation and examples. ## Ground rules that come from the PRD These are not style preferences — they are product requirements: - **One operation layer** (PRD §7.2). The UI, CLI, API, and MCP server must call the same validated operations. Do not add a second implementation of document logic in an adapter or in the MCP server. - **Determinism is a feature** (PRD §7.5). If an operation can be deterministic, it must be. Provider-dependent operations must record provider, parameters, and seed. - **AI stays optional** (PRD FR-15). The core must never require an AI provider, a cloud account, or network access. - **Protected content is respected** (PRD §10.2). Normal operations and AI adapters must not mutate `locked`, `protected`, and `readOnly` layers. - **No private content in this repository** (PRD §7.6, R5). Never commit brand kits, customer assets, credentials, or downstream business logic. Use neutral fixtures and example assets. - **Every mutation is reversible** (PRD FR-8). This includes MCP-triggered writes. ## Proposing a change 1. **Open an issue first** for anything beyond a typo or a docs fix. This applies especially to schema changes, new layer types, new MCP tools, and new dependencies. 2. **Discuss scope.** Say explicitly if the change belongs in the core or in an adapter. Say which PRD requirement it serves. 3. **Keep pull requests small and single-purpose.** A PR that changes the document schema and adds a renderer feature and adds an MCP tool is three PRs. A release pull request is the exception: it holds one whole version, including its documentation and version bump. ## Changes that need extra scrutiny Expect a slower review, and please open an issue before you write code: - **Document schema changes.** These affect persistence, migration, every renderer, and every downstream consumer. Include the schema version bump and the migration path. - **New dependencies.** Record the license before you propose it (PRD R8). We do not accept a dependency because its demo looks good. License terms, serialization behavior, export reliability, testability, and agent access matter more (PRD §14). - **New MCP tools.** Read-only tools come before mutating tools. Mutating tools need dry-run, expected-version checks, protected-layer checks, and an undo transaction ID (PRD FR-13). - **Anything that touches the filesystem boundary.** MCP tools must stay inside the configured project root (PRD §10.1). ## Testing expectations Tests must run without a live cloud provider or paid API (PRD NFR-5). We expect coverage for: document validation, layer and group operations, transforms, ordering, protected-layer behavior, serialization and migration, operation history, rendering, export, and MCP tool schemas (PRD §17). The end-to-end smoke test must create a document, add text and image layers, save it, reload it, request a preview, apply one MCP mutation, undo it, and export a PNG. **No release may be described as working until that smoke test has run successfully on both Windows and Linux.** ## Documentation expectations Every public operation, document field, MCP tool, and extension point needs documentation and an example (PRD NFR-7). Do not document a capability as supported until it is implemented and verified. The README's claims follow the same rule. ## Versioning Releases follow [Semantic Versioning](https://semver.org/) (`MAJOR.MINOR.PATCH`). The document `schemaVersion` is an independent integer: a schema change always increments it and must ship with a migration path. This rule applies regardless of the release version. If your change touches the document schema, say so in the PR and include the migration. See PRD §16.1 for the full policy. ## How a version is released One version is in work at one time. Each version uses one branch and one pull request. The tag comes after the merge. 1. **Branch.** Create `release/X.Y.Z-` from `origin/main`. Do not start from a local `main` that differs from `origin/main`. 2. **Build.** Add one plan step for each commit group. Each commit builds, and its tests pass. 3. **Review.** Run the format check, the lint check, the dependency check, and the test suite. Read the full diff. 4. **Version and documentation.** Bump every version string and update the release documentation in the same commit. The file [skills/version-pipeline/SKILL.md](skills/version-pipeline/SKILL.md) lists the files. 5. **Pull request.** Open one pull request to `main`. The pull request holds the whole version: code, tests, documentation, and the version bump. 6. **CI.** The full six-target matrix must pass. One re-run of a failed job is permitted. A second failure is a defect. 7. **Merge.** Merge with a merge commit. Confirm that `main` is green on the merge commit. 8. **Tag.** Create an annotated tag `vX.Y.Z` on the merge commit, then push the tag. The Release workflow builds the six targets and attaches the assets. 9. **Publish.** Create the draft release. Verify the assets and the checksums. Download one archive and run it. Then publish as the latest release. The Homebrew formula needs the hashes of the published archives. Update it in one short pull request after publication. Do not tag a commit that is not green. Do not describe a release as working until its smoke checks ran. ## Branch names Use one form for work that ships: ```text release/X.Y.Z- ``` - Put the version that will ship the work in the name. A new capability ships in a MINOR version: `release/1.14.0-page-sets`. A defect fix ships in a PATCH version: `release/1.13.1-arm-lock-race`. - Use lowercase letters, digits, and hyphens. - Open one `release/` branch for each version at a time. That branch is the one that gets the tag. - Delete the branch after its tag exists. - Never start a branch with a tool or agent name. - Use `chore/` for repository work that ships with no version. - Use `spike/` for an experiment. Never merge a spike branch. ## Commit and PR conventions - Write commit messages in the imperative mood: "add group transform validation", not "added" or "adds". - Reference the issue and the relevant PRD requirement where one applies (for example, `FR-7`, `NFR-3`). - Note explicitly in the PR description if the change alters the document schema, the public API surface, or MCP tool behavior. ## Licensing of contributions Assemblash is licensed under the [Apache License 2.0](LICENSE). When you submit a contribution, you agree that it is licensed under the same terms (Apache-2.0 §5). Do not submit code that you do not have the right to license this way. ## Security issues Do not open a public issue for a vulnerability. Follow [SECURITY.md](SECURITY.md).