Files
Integration-kit/CONTRIBUTING.md
wtclaude cffd525bdf
All checks were successful
PR Checks / template (pull_request) Successful in 6s
PR Checks / links (pull_request) Successful in 7s
docs: scaffold the Integration Kit — front page, outline, and the checks
Phase 5 slice 0 (MODULE_SYSTEM.md §2.11.1). The repo's governance, the front
page, the book's outline, and the CI that keeps the whole thing from rotting.

README.md
  What the reader is building, all three parts, and the draft banner: the kit is
  finished when someone outside this project builds a working module by
  following it alone, and that has not happened. Says the sidecar rule plainly
  (MODULE_API.md §2.7) rather than leaving it to chapter 3, because a reader who
  skims the front page and starts coding should still get that one right.

book/README.md
  The outline of four chapters, landed before the prose so the shape can be
  argued with. Chapters are named but NOT linked — a link to a file that does
  not exist is what the link check is for, and an outline should not be the
  first thing to fail it.

CONTRIBUTING.md
  The rule that governs every change here: the kit never re-specifies a
  contract. Also the prose conventions, and why the pinned ref points at core's
  `edge` rather than `main`.

SECURITY.md
  Scoped for a repo that runs nothing: the two things that ARE reportable are a
  template that teaches an insecure pattern (it is meant to be copied) and a
  chapter that teaches something dangerous.

scripts/checkLinks.js
  Relative links resolve; anchors match a real heading; no link pins a reader to
  a commit snapshot of a moving document. Nothing is fetched — a self-hosted
  Gitea would fail on a credential-less runner and teach us to ignore red.
  Fences and code spans are stripped by a line walk, not a regexp.

  Its first run found a real one: a PR template's relative links resolve from
  the REPO ROOT, because that is where their text ends up when Gitea inlines
  them into a pull request body. Encoded, with the reason.

scripts/checkCoreApi.js
  The anti-rot check. Asserts template/module.json's `coreApi` EQUALS the pinned
  core's MODULE_API_VERSION — equality, not "satisfies", because a range check
  stays green across a contract bump and green would then mean "the template
  still loads" instead of "someone has re-read the book". Both failure branches
  and the pass were exercised against a real core checkout.

ci/core-ref.json
  The pin, same convention as Module-uo's. Points at `edge`: core's `main` has
  no server/src/modules/ until the cutover, and that pin is one of the things
  the cutover has to revisit.

.gitea/workflows/pr-checks.yml
  Two jobs. `links` always runs; `template` is conditional on
  template/module.json existing, so the repo is gated now and the job arms
  itself when slice 1 lands, with no edit to the workflow. Same guard Module-uo
  used through its planning phase.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-12 09:47:22 -05:00

6.4 KiB

Contributing to Runic Gateway — Integration Kit

Thanks for your interest! This repo is the Integration Kit: the instruction book for putting a game that is not Ultima Online onto a Runic Gateway site, plus a template/ module that builds.

It is the only repo in this project written for someone outside the organisation, and that changes what a contribution looks like here. Elsewhere the docs record decisions; here they teach a stranger. The most valuable contribution is not a correction — it is a report of the place you got stuck and what you did next.

By participating you agree to abide by our Code of Conduct.

Status: draft

The kit's acceptance test is that someone outside this project builds a working module for a new game by following it alone, without reading core's source. Until that has happened it is a draft however finished it looks, and the README says so on the front page. Do not remove that banner in a PR that is not the one recording a passed acceptance run.

The rule that governs every change here

The kit never re-specifies a contract. These are normative; the kit teaches and links out:

So: do not copy a member list, a field table or a set of rules into a chapter. Quote the part you are explaining, with a link, and let the reader go to the authority for the whole. A guide that restates a contract diverges from it silently, and the reader who follows the divergent copy gets a module that fails validation for reasons the guide cannot explain.

If a rule looks wrong rather than badly explained, that is a docs-repo PR against MODULE_API.md, not a change here. The kit does not get to disagree with the contract in prose.

Ways to contribute

  • Report where the kit failed you through the issue tracker — templates provided. "I could not work out how to X" is a bug in this repo.
  • Fix or extend a chapter, or the template, with a pull request.
  • Never report a security vulnerability in a public issue — see SECURITY.md.

Working on this repo

Prerequisites: Node 20+, and a checkout of RunicGateway/website if you are touching template/ — a module is not runnable on its own.

node scripts/checkLinks.js          # every relative link resolves; no commit permalinks

The template's own checks live under template/ and are described in the chapter that introduces it.

What CI checks, and why it is shaped that way

.gitea/workflows/pr-checks.yml clones core at a pinned commit and then:

  1. asserts the version template/module.json declares still equals that core's MODULE_API_VERSION;
  2. builds the template and runs its boundary guards;
  3. runs the link check over every markdown file.

Check 1 is the anti-rot mechanism. A contract bump in core changes that number, this repo goes red, and someone has to look at whether a chapter has become untrue — which is the half a machine cannot check. That is also why a MODULE_API_VERSION bump in core carries an obligation to pass over this kit in the same PR (MODULE_SYSTEM.md §2.10).

The pin points at a commit on core's edge branch, not main. The module system has not cut over yet; main has no server/src/modules/ at all. Moving the pin is a deliberate, reviewed change — it is the moment someone re-reads the chapters — so it is a line in the workflow rather than a floating branch name.

Prose conventions

  • Second person, present tense. "You register a route", not "the module author registers a route".
  • Say why before how. Every rule in this project exists because something broke; a rule without its reason is one the reader will route around.
  • Examples are quotations. Code blocks come from template/ or from a real repo, with a path next to them. An invented example is one nobody has compiled.
  • Own the mistakes. Where this project got something wrong and paid for it, the kit says so plainly. That is the part a reader cannot get anywhere else.
  • One sentence per line is not required, but keep lines under ~100 characters.

Commit messages

Conventional Commitstype(scope): summary. docs: for chapters, feat:/fix: for the template, ci: for workflows.

Branch & PR workflow

  1. Branch from main (feature/…, fix/…, docs/…, chore/…).
  2. Keep it focused.
  3. Open a pull request against main and fill in the template, including the AI-assisted contributions disclosure.
  4. A maintainer reviews; address feedback with follow-up commits.

This repo develops on its own main from its first commit — no edge, no cutover.

AI-assisted contributions (disclosure required)

This project is developed openly with AI assistance, and we ask the same transparency of everyone. If you used an AI tool (Claude, Copilot, ChatGPT, Cursor, etc.) to help produce a contribution, you must disclose it:

  • Tick the AI-usage box in the pull-request template and name the tool(s).
  • Mark AI-authored commits with a trailer, e.g. Co-Authored-By: Claude <noreply@anthropic.com> or Assisted-By: <tool>.
  • You remain responsible for every line you submit: review it, understand it, and make sure it is correct and that you have the right to contribute it.

Disclosed AI assistance is welcome. Undisclosed AI-generated contributions are not, and may be closed.

License

Runic Gateway is licensed under the GNU General Public License v3.0 or later (see LICENSE.md). By submitting a contribution you agree that it is licensed under the same terms (inbound = outbound) and that you have the right to contribute it.