Skip to content

Contributing

How to contribute to ZERG. This guide covers code style, commit conventions, the PR process, and review expectations.

Code Style

Erlang (Sol Server)

Use the logger module for all logging. Never use io:format in production code:

erlang
logger:info("scheduler: created job ~p", [JobId]).
logger:warning("auth failed for token ~p", [TokenHint]).
logger:error("zmq gateway crashed: ~p", [Reason]).

Use process_flag(trap_exit, true) in all gen_servers that own resources (OS processes, ETS tables, sockets). ETS tables must use {heir, Pid} to survive owner crashes.

gen_server:call must always use a timeout constant, never bare calls:

erlang
-define(CALL_TIMEOUT, 5000).

handle_call({create_job, Spec}, _From, State) ->
    gen_server:call(?MODULE, {create_job, Spec}, ?CALL_TIMEOUT).

For fire-and-forget operations that reply to From, use spawn + erlang:monitor instead of spawn_link to avoid killing the calling gen_server on failure.

Lua (Luna Client)

Use cel.json for all JSON operations. Do not import dkjson or JSON_luerl directly:

lua
local json = require("cel.json")
local data = json.decode(raw)
local encoded = json.encode(data)

Use cel.class for all OOP (middleclass v4.1.1):

lua
local MyClass = require("cel.class")("MyClass")

function MyClass:initialize(config)
    self.config = config
end

return MyClass

Use cel.shell_quote for all shell arguments to prevent injection:

lua
local shell_quote = require("cel.shell_quote")
os.execute("cat " .. shell_quote(filename))

Return nil, err on errors:

lua
function MyClass:execute(args)
    if not args then
        return nil, "args required"
    end
    return result
end

Python (Mango)

Follow PEP 8 with Tornado conventions. Use type hints where practical.

TypeScript/Vue.js (Limon)

Follow the existing component structure. Use Composition API with <script setup>.

Module Naming

ComponentConventionExample
Sol HTTP handlerssol_http_<domain>.erlsol_http_memory.erl
Sol gen_serverssol_<domain>.erlsol_scheduler.erl
Sol storessol_<domain>_store.erlsol_scheduler_store.erl
Luna corecore/<feature>.luacore/redaction.lua
Luna toolscore/tools/<tool>.luacore/tools/web_search.lua
Luna FFIffi/<lib>.luaffi/zmq.lua
Mango systemsmango/systems/<name>.pymango/systems/auth.py

Commit Conventions

Use concise, descriptive commit messages in imperative mood:

add pgvector memory search endpoint
fix scheduler missed-job detection for cron schedules
refactor auth middleware to use persistent_term cache

Prefix with component when ambiguous:

sol: add admin check to infra maintenance endpoints
luna: fix shell quoting for MCP OAuth callback URL
mango: seed admin RBAC on setup_db

PR Process

Before Submitting

  1. Run the full test suite and confirm no new failures:
bash
cd server && rebar3 eunit
cd client && for f in tests/test_*.lua; do luajit "$f"; done
cd mango && python3 -m pytest tests/ -v
  1. Verify existing tests still pass. All tests pass with 0 failures.

  2. If adding new endpoints, add corresponding test coverage.

  3. If modifying authentication or authorization logic, add security tests.

PR Description

Include:

  • What the change does
  • Why it is needed
  • Test coverage added
  • Any breaking changes

Code Review Expectations

Reviewers check for:

  • Correct OTP patterns (trap_exit, ETS heir, gen_server timeouts)
  • Proper error handling (no silent catches, no swallowed errors)
  • Security implications (input validation, auth checks, shell quoting)
  • Test coverage for new code paths
  • Documentation updates for API changes

Adding New Test Files

Erlang Tests

Create server/test/sol_<module>_tests.erl with eunit test functions.

Lua Tests

Create client/tests/test_<feature>.lua following the helper pattern with ok and check functions. Exit with code 1 on failure.

Test Naming

Test names should describe the specific behavior being verified:

erlang
memory_store_with_ttl_test() ->
    ...

memory_store_missing_key_returns_400_test() ->
    ...

License

ZERG is released under the MIT License. By contributing, you agree that your contributions will be licensed under the same terms.

Released under the MIT License.