Skip to content

Contributing

Lace is an open-source project under the Apache 2.0 license. Contributions are welcome from anyone -- spec improvements, new executor implementations, conformance vectors, tooling, and documentation.

Conventions

  • Naming: camelCase for identifiers, field names, and API surfaces. SCREAMING_SNAKE_CASE for error codes only.
  • Documentation: every spec or behaviour change must update the relevant docs and wiki pages under wiki/docs/.
  • No purely stylistic changes: refactoring whitespace, rewording comments, or reformatting code without a functional reason will not be accepted.

Proposing Spec Changes

The spec (specs/lace-spec.md, specs/lace-extensions.md) defines the language. Changes to the spec affect every executor implementation, so they require careful consideration.

  1. Open an issue or discussion if you want feedback before implementing. This is optional -- you can also go straight to a PR.
  2. Open a PR with the proposed changes. Include:
    • The spec prose change
    • Updated grammar (specs/lacelang.g4) if syntax is affected
    • Updated JSON schemas (specs/schemas/) if wire formats change
    • Updated error codes (specs/error-codes.json) if new codes are needed
    • Updated checklists (specs/checklist-core.md or specs/checklist-extensions.md)
    • Updated wiki pages (wiki/docs/)
    • New or updated conformance vectors (testkit/vectors/)
    • An entry in the changelog (CHANGELOG.md)
    • Updates to relevant README files
  3. Run make verify in specs/ before submitting.
  4. Discussion happens in PR comments. A maintainer must approve before merge.

Adding Conformance Vectors

New test vectors exercise specific spec behaviours. To add one:

  1. Pick the right testkit/vectors/NN_* directory.
  2. Copy an existing vector as a template.
  3. Run npm run check-vectors from specs/tools/ to validate the format and error-code references.
  4. Run lace-conformance against a reference executor to confirm the vector passes.

Improving the Grammar

If you change specs/lacelang.g4:

  1. Add at least one sample to specs/grammar-tests/positive/ or specs/grammar-tests/negative/ demonstrating the change.
  2. If the change affects the AST structure, update specs/schemas/ast.json and add a parse conformance vector.
  3. Run make verify in specs/.

Registering a New Executor Implementation

Lace is designed for independent executor implementations in any language. To register yours:

  1. Ensure your executor passes the conformance suite:

    lace-conformance -c "your-executor-command"
    
  2. Open a PR adding a link to the "Known executor implementations" table in README.md. Include:

    • Repository URL
    • Language
    • Conformance level (full or partial, with omissions listed -- see Conformance Levels)
    • Spec version it conforms to (from lace-executor.toml [executor].conforms_to)
  3. The maintainers will review your implementation, verify conformance, and approve.

See the Core Checklist and the Extension Checklist for the full list of behaviours your executor must support, and For Implementers for a guided walkthrough.

Documentation and Wiki

The wiki lives in wiki/docs/ and is built with mkdocs-material. When changing spec behaviour, update the corresponding wiki page -- the wiki is the user-facing documentation, the spec is the implementer reference.

To preview locally:

cd wiki
pip install mkdocs-material
mkdocs serve

Verifying Spec Artifacts

cd specs
make verify

This runs:

  1. Grammar -- generates the parser from lacelang.g4, then parses every sample under grammar-tests/{positive,negative}/. Positives must parse cleanly; negatives must produce parse errors.
  2. Schemas -- compiles every JSON schema under schemas/ and verifies the error-code registry has no duplicates.
  3. Extensions -- TOML-parses every .laceext under ../extensions/ and validates against the laceext schema.
  4. Vectors -- validates every conformance vector under ../testkit/vectors/ against the vector schema and cross-checks referenced error codes against the registry.

Requires Java (any JDK 11+) on PATH for the grammar tests and Node.js on PATH for the schema, extension and vector checks. Only the ANTLR jar is downloaded automatically (into build/ on the first grammar run); the Node dependencies are installed into tools/node_modules/ by make tools-deps, which the checks run first.

Version

The current spec version is defined in the VERSION file at the repository root. Spec, grammar, schemas, error codes, conformance vectors, and the testkit all share this version. Executor implementations declare which spec version they conform to via lace-executor.toml.

The version is bumped only when the specification changes in a way that affects executor behaviour or wire formats -- new syntax, new result fields, changed semantics, new error codes, etc. Refactoring prose, fixing typos, reorganizing documentation, adding wiki pages, or updating tooling does not warrant a version bump. If an executor built against the previous version would still pass the conformance suite unchanged, the version stays the same.

Re-baking the Docs After a Bump

Markdown carries specVersion / vectorCount placeholders (the name wrapped in double curly braces) that a git clean filter bakes into concrete values at commit time. The filter is per-clone -- configure it once after cloning:

bash testkit/setup-filters.sh

When you bump VERSION or a vector COUNT, re-run that script and commit the renormalized markdown in the same PR as the bump. The Bake check workflow fails any PR whose committed markdown does not match the current values -- the bake is a manual step, deliberately: no automation rewrites docs behind your back.

Review Process

All contributions require approval from a project maintainer before merge. Discussion happens in PR comments -- no separate approval process is needed.

License

By contributing, you agree that your contributions will be licensed under the Apache License 2.0, the same license as the project. See License.