Overview
Open-source release toolchain for Godot 4. Not a fork. Not DRM. Not anti-cheat.
Export a Godot game that stock GDRE/KeyDot cannot one-click recover, without maintaining a fork. This raises the cost of automated recovery. It does not make a local client unextractable.
Designers keep the official Godot editor. Custom export templates are built in Docker or CI from a pinned Godot tag plus a small patch quilt. Production exports refuse to ship source, and fortressgd verify fails CI if they did.
Supported engine tags: Godot 4.6.2 and 4.7.2 stable (4.7 and 4.7.x in config mean 4.7.2). Other 4.7 patch releases are not supported until they have a patch folder. See DESIGN.md §4.
Start with leak checks on the official editor — no Docker, no custom templates. Add derived-key encryption, pack dialect, and mangling when you are ready to ship a Release PCK.
Features
Section titled “Features”Export hygiene
- Production presets skip GDScript text, C# source files, .NET
.pdbsymbols, DCC work files, plugin internals, and source maps unless you allowlist a path - Shaders: Godot ships
.gdshader/.gdshaderincas plain text.verifyfails if a packed shader still contains//or/* */comments; strip them before release, or list the path in[filters].includeto accept it. FortressGD does not minify shaders yet - C# caveat: a .NET game still ships its compiled assembly, which decompiles to near-original C#. FortressGD does not obfuscate it;
doctorandexportwarn on .NET projects (seeTHREAT_MODEL.md) - Official-editor workflow: add the
fortressgd_productionfeature tag and export as usual fortressgd verifylists packed paths and fails CI if excluded files leaked
Derived encryption key
- PCK AES-256 key is derived from the project secret (
FGD-KDF-1, HKDF-SHA256) when the template is built. The template never holds it as a raw 32-byte blob next to a known error string - Per-build code: the code that stores and decodes the key and the dialect values is generated per
(secret, Godot version, key_epoch). The key is split into 3–8 pieces of random sizes, each stored under its own chain of operations and decoded by its own routine (DESIGN.md §18.3). A tool written to read the key out of one build without running it should not work on a build with another secret or epoch; the e2e workflow checks this with a reference extractor and a machine-code comparison. That shows builds differ. It does not show that no static extractor for FortressGD builds in general can be written - The project secret itself never ships: no template or pack contains it, so extracting a build’s key does not reveal the secret or the signing seed. That key does open every build of the project for the same Godot version and key epoch, until you bump
key_epochor rotate the secret - Custom
template_releasebinaries, relinked per project in a prebuilt build image:templates buildcompiles one generated file and relinks instead of compiling Godot (see Templates) - CLI injects the derived key for one export process only; it is never written to
export_presets.cfg
Per-project pack dialect (optional, on by default in the example config)
- Pack magic and index field order come from the project secret
- Stock GDPC parsers cannot list the pack;
verifyrequires that they fail - Export uses the shared FortressGD export editor (
--export-pack), built once per Godot tag; designers still use the official editor day-to-day
GDScript mangling (optional, on by default in the example config)
- Strips comments,
assert,print_debug, andbreakpoint - Renames user identifiers with an HMAC keyed from the project secret, so names cannot be reversed without it (not from
secret_hash, which appears in logs and cache keys) - Unmarked
call("name")/rpc("name")/set("prop")fail the export — use Callables - Never rewrites scripts under
addons/; names an addon mentions stay unmangled in your scripts - Leaves names alone that it cannot follow: members accessed on other objects, names in string literals,
@exportvars, and names used in scenes, resources andproject.godot fortressgd mangle-reportlists every name left readable, the rule that kept it and the file that triggered it (no secret needed);exportprints a one-line summary- Writes the source map (
*.fortressgd.map.json) to.fortressgd/maps/in the project, never inside the pack or next to the artifact: the map reverses all mangling, and build folders get uploaded whole.fortressgd initsuggests git-ignoring.fortressgd/, andverifyfails if a map sits next to an artifact
Nameless bytecode (off by default)
- Packed
.gdcomits stock identifier/line tables; runtime names live in anFGDNtrailer verifyfails if those debug tables are still present
Pack signatures (off by default)
- Ed25519 signature over the pack index
- Public key is compiled into the template; the private seed is derived from the project secret and is not persisted. The secret never ships, so extracting a template’s pack key does not let anyone sign packs
Toolchain
- One config file (
.fortressgd.toml, committed, no secrets) - CLI + editor plugin share the same backend
- GitHub Action to build and cache templates
doctorchecks config, Godot version, plugin drift, and secret presence
What it does / does not
Section titled “What it does / does not”Does
- Keep the official editor for day-to-day work
- Relink
template_releasebinaries per project in a prebuilt, digest-pinned build image (Godot compiled once fromfortressgd/patches/<godot-tag>/) - Derive the PCK AES key (
FGD-KDF-1) instead of embedding the raw blob - Optionally change pack magic and index layout per project secret
- Strip source (
.gdtext,.cs, DCC files, source maps) from Release - Optionally mangle GDScript identifiers at export
- Fail export or CI when the artifact is still a recoverable project
Does not
- Maintain a Godot fork
- Virtualize the exe (no VMProtect-class packer)
- Stop debugger memory dumps
- Protect macOS / Android / iOS / Web in v1 (vanilla export only; do not claim those are protected)
- Replace a server for secrets or anti-cheat
A debugger can still dump decrypted resources from a running client. That is accepted and written down in THREAT_MODEL.md.
Requirements
Section titled “Requirements”- Python 3.9+
- Godot 4.6.2 or 4.7.2 (official editor on
PATH, orGODOT/FORTRESSGD_GODOT) - Docker, for template builds
- A 32-byte secret, 64 hex chars, not in git (
.fortressgd.secretorFORTRESSGD_SECRET)
You do not need SCons or a local Godot source tree on designer machines.
Protected platforms in v1: Windows and Linux (x86_64). Other Godot export presets may still run vanilla; they are not FortressGD-protected.
Install
Section titled “Install”Install the wheel attached to a release. The editor plugin, the engine patches, the Docker build files and the digests of the release’s build images ship inside it, so you do not need a checkout:
pip install "fortressgd @ https://github.com/salaryman-inc/FortressGD/releases/download/v0.2.0/fortressgd-0.2.0-py3-none-any.whl"cd /path/to/your/godot/projectfortressgd --versionInstall the wheel, not a git tag. A git install has no image digests, so templates build compiles each build image on your machine the first time (35–45 minutes per platform on a GitHub-hosted runner). docs/releasing.md shows how to check the wheel and the images with gh attestation verify.
Run every command from your Godot project root (the directory with project.godot).
To run from a source checkout without installing, use bin/fortressgd (or python3 -m fortressgd from the checkout root):
python3 /path/to/FortressGD/bin/fortressgd --helpFortressGD has no required dependencies. For large projects, install the optional fast extra: it adds the cryptography package so pack encryption and decryption (in verify, export signing, and the nameless-bytecode check) run through OpenSSL, roughly 700× faster than the built-in pure-Python AES. Both produce identical bytes.
pip install "fortressgd[fast] @ https://github.com/salaryman-inc/FortressGD/releases/download/v0.2.0/fortressgd-0.2.0-py3-none-any.whl"Quick start
Section titled “Quick start”Hygiene-only (official editor, no Docker): see docs/getting-started.md.
Full production export (derived key + dialect + mangling):
cd /path/to/your/godot/project
# 1. Config, plugin, .gitignorefortressgd init
# 2. 32-byte secret (mode 0600). Never commit this file.fortressgd secret generateexport FORTRESSGD_SECRET="$(cat .fortressgd.secret)"
# 3. init already enabled the FortressGD plugin in project.godot.# On the Release preset: GDScript Export Mode = Binary tokens (or compressed),# and add the custom feature tag fortressgd_production.
# 4. Build custom templates (Docker). Repeat per platform you ship. The first# run pulls the release's build image; each build relinks in it.fortressgd templates build --godot 4.6.2 --platform linuxfortressgd templates build --godot 4.6.2 --platform windows
# 5. Export. With verify_on_export = true (the default) export also runs verify# and exits 2 on a leak. Run verify on its own in CI or on any artifact.fortressgd export --preset Linuxfortressgd verify path/to/your_game.pckRotating FORTRESSGD_SECRET requires rebuilding templates. Old packs will not load. That is intended. See the rotation runbook in docs/secrets.md.
Hygiene only (no custom templates)
Section titled “Hygiene only (no custom templates)”Use this first. It keeps source and work files out of a Release pack and proves it with verify.
cd /path/to/your/godot/projectfortressgd initinit also enables the FortressGD plugin in project.godot. Then in the official editor:
- Open Project → Export on the Release preset (not debug).
- Set GDScript Export Mode to Binary tokens or Compressed binary tokens.
- Add the custom feature tag
fortressgd_production. - Export PCK/ZIP or a full project as usual.
fortressgd verify path/to/game.pck# also: fortressgd verify path/to/game.exeExample success:
ok: no production leaks in game.pck (42 packed files)Example failure (exit 2):
error: leaked or unencrypted file(s) in game.pck res://main.gd (*.gd) res://icon.psd (*.psd)Run: fortressgd doctorAllowlist a path that would otherwise fail (for example a text script a mod hook needs):
[filters]include = ["mods/hook.gd"]Re-export, then fortressgd verify again.
Presets without fortressgd_production are not force-filtered. Keep a debug preset without the tag.
Encrypted Release PCK (derived AES key)
Section titled “Encrypted Release PCK (derived AES key)”When you are ready so stock KeyDot cannot one-click extract a 32-byte key. Turn dialect off to stay on official encrypt-PCK:
[production]dialect = falsemangle_scripts = falseexport FORTRESSGD_SECRET="$(cat .fortressgd.secret)"fortressgd doctorfortressgd templates build --godot 4.6.2 --platform linuxfortressgd export --preset Linux # verifies the artifact when verify_on_export = truefortressgd verify build/game.pck # the same check, for CI or a copied artifactexport sets GODOT_SCRIPT_ENCRYPTION_KEY to FGD-KDF-1(secret, salt) for that process only, points the preset at the cached FortressGD template, turns on PCK and directory encryption, and restores export_presets.cfg afterwards.
Godot encrypts a file’s contents only when its path matches the preset’s Encryption Include Filters, and an empty filter encrypts no contents at all, only the file list. So when that filter is empty, export sets it to * for its run and every file body is encrypted. A filter you set yourself is kept, for example to leave large media unencrypted for load speed; scripts must still match it. Missing templates print the exact templates build command to run.
The exported pack’s directory is encrypted with that derived key, so verify reads it with the project secret and the godot version from .fortressgd.toml. Without the secret, verify exits 1 and says so. In a pack with an encrypted directory, verify exits 2 if no file body is encrypted (the empty-filter mistake) or if any script body is unencrypted; [filters].include exempts a path.
Full production (dialect + mangling)
Section titled “Full production (dialect + mangling)”This is the example .fortressgd.toml default:
[production]dialect = truemangle_scripts = truenameless_bytecode = falsesign_packs = falseexport FORTRESSGD_SECRET="$(cat .fortressgd.secret)"
fortressgd templates build --editor --godot 4.6.2 # once per Godot tag; needs no secretfortressgd templates build --godot 4.6.2 --platform linuxfortressgd export --preset Linux # verifies the artifact when verify_on_export = truefortressgd verify build/game.pck # the same check, for CI or a copied artifacttemplates build produces template_release binaries (the runtime). Dialect packing needs the FortressGD export editor: a headless Godot editor with the same patches. templates build --editor builds it in Docker for Linux and caches it as godot-<ver>-editor-linux-x86_64-fgd<patchset>-p<id>. It is the same for every project. export passes the project’s pack magic and index field order to it in FORTRESSGD_PACK_PARAMS, for that one export only, and runs --export-pack. The pack key goes in GODOT_SCRIPT_ENCRYPTION_KEY, as for a stock export.
export fails if the pack it gets back is not in the project’s dialect, for example when it ran the official editor. A stock GDPC listing of the pack must fail; verify checks that. --export-pack writes only the pack: ship the cached template as the game’s executable, with the pack next to it under the same name ending in .pck.
On a host other than Linux, build or point at a patched editor yourself with FORTRESSGD_EDITOR.
With mangling on, unmarked string call / rpc / set fail the export. Use Callables, or mark a required string API:
## fortressgd:keepcall("public_mod_hook")See docs/agent-rules.md.
Nameless bytecode and pack signatures
Section titled “Nameless bytecode and pack signatures”Both stay off until you opt in.
nameless_bytecodeis checked byverifyonly. Every FortressGD template can load nameless bytecode, so toggling it needs no template rebuild.sign_packsneeds the signature-required template variant (its name ends in-sig). Rebuild templates after turning it on:templates buildreadssign_packsfrom.fortressgd.toml(or pass--require-signature; the GitHub Action takessign_packs: "true"). That template refuses packs whose index signature is missing, zeroed, or invalid, including encrypted packs.exportsigns the pack and fails if only the non--sigtemplate is cached. Encrypted sparse bundles (Godot 4.7) cannot be signed.
[production]nameless_bytecode = truesign_packs = truefortressgd templates build --godot 4.6.2 --platform linuxfortressgd export --preset Linuxfortressgd verify build/game.pckverify then fails if packed .gdc still has debug name tables, or if the Ed25519 index signature is missing or invalid.
With nameless_bytecode = true, set the preset’s GDScript Export Mode to Binary tokens unless CI runs Python 3.14+: verify decodes “Compressed binary tokens” (ZSTD) only with Python 3.14’s compression.zstd, and otherwise fails with that reason rather than passing unchecked. Encrypted .gdc bodies are decrypted with the project secret before the check.
Templates and build images
Section titled “Templates and build images”A dialect template (dialect = true) is relinked, not compiled. Each release publishes one build image per Godot version and platform to ghcr.io/salaryman-inc/fortressgd-build. It holds Godot compiled once from the release’s patches, and no secret. templates build:
- generates
fortressgd_gen.cppfrom the secret, on the host (the secret never enters a container), - pulls the build image by the
@sha256:digest pinned in the installed wheel, - compiles that one file in the image and relinks the template, then scans it for secret material and caches it.
A warm build (image already pulled) takes about 9 minutes per Linux template on a GitHub-hosted runner: Godot links with full LTO, so the relink reoptimizes the whole program. A Windows template relinks in seconds. Times are in docs/ci.md.
fortressgd doctorsays whether each pinned image is pulled.templates build --from-sourcecompiles all of Godot in a fresh container instead (30–60 minutes per platform), for when you will not run a prebuilt toolchain.templates build --image REFrelinks in an image you name, one platform at a time.- Templates with
dialect = falseand the shared export editor (--editor, about 35 minutes, once per Godot tag and machine or CI cache) are still compiled from source; they do not have build images yet.
Configuration
Section titled “Configuration”.fortressgd.toml lives at the project root and is committed. It must not contain the secret. fortressgd init writes the example file. Unknown keys are errors.
schema = 1godot = "4.6.2"
[production]dialect = truekey_epoch = 0mangle_scripts = truenameless_bytecode = falsesign_packs = falseverify_on_export = true
[filters]exclude = [ "*.cs", "*.sln", "*.csproj", "*.blend", "*.psd", "*.kra", "*.tmp", "*.fortressgd.map.json",]include = []
[platforms]build = ["windows", "linux"]
[templates]cache_dir = "~/.cache/fortressgd"| Key | Meaning |
|---|---|
schema |
Config version. Must be 1. |
godot |
Engine tag: 4.6.2 or 4.7.2 (4.7 / 4.7.x are aliases for 4.7.2). doctor rejects tags without a patch folder. |
production.dialect |
Per-secret pack magic + index layout. |
production.mangle_scripts |
Rename identifiers and strip debug statements. |
production.nameless_bytecode |
Omit stock .gdc debug name tables. |
production.sign_packs |
Ed25519 signature over the pack index. |
production.key_epoch |
Integer, default 0. Changes only the pack AES key; the pack format, signing key and mangled names stay the same. Bump it for a new release line so a key extracted from one release does not open the next; rebuild templates afterwards (their names gain -e<N>). Patch or DLC packs must use the same epoch as the game that loads them. |
production.verify_on_export |
Keep true (the default when absent). export then runs the same check as fortressgd verify on the artifact, or on the <name>.pck next to an executable without an embedded pack, and exits 2 on a leak. .zip exports are not supported yet. |
filters.exclude |
Extra exclude globs (forced excludes still apply). |
filters.include |
Allowlist that overrides a forced exclude. |
platforms.build |
Default platforms for templates build. |
templates.cache_dir |
Template cache root (default ~/.cache/fortressgd). |
Production exports also force-exclude GDScript text (bytecode only) and addons/fortressgd/** unless the same pattern is in include.
Secret sources, in order: --secret-file (default .fortressgd.secret), then FORTRESSGD_SECRET. Never print the secret; secret status only reports present/missing. For managed stores (KMS, CI secrets) and rotation, see docs/secrets.md.
Commands
Section titled “Commands”fortressgd initfortressgd doctor [--godot X.Y.Z]fortressgd secret generate | fortressgd secret statusfortressgd templates build [--godot X.Y.Z] [--platform windows|linux]fortressgd templates listfortressgd export --preset NAMEfortressgd verify PATH.pck|PATH.exefortressgd mangle-report [--json] [--all]Every command accepts --secret-file PATH. --platform is repeatable (--platform linux --platform windows).
| Command | What it does |
|---|---|
init |
Write .fortressgd.toml if missing, install addons/fortressgd, suggest/append .gitignore for .fortressgd.secret. |
doctor |
Validate toml, supported Godot tag, plugin files vs CLI package, secret presence and hygiene. Fails on a weak or placeholder secret, or a secret file readable by group or others. A missing secret and plugin drift are warnings, not failures. |
secret generate [--force] |
Write 32 CSPRNG bytes as 64 hex chars, mode 0600. Refuses to replace an existing secret without --force; a new secret cannot load packs or use templates built with the old one. |
secret status |
present / missing; never prints the secret. |
templates build |
Build template_release for (godot, secret_hash, platform, key_epoch): relink in the release’s pinned build image for a dialect template, or compile in Docker. --from-source, --image REF, --editor. |
templates list |
Names of cached templates. |
export |
Production export with derived AES key (and dialect/mangle/sign when enabled), then verify when verify_on_export is true. |
mangle-report |
List the script names mangling leaves readable, grouped by the rule that keeps each one (scene/resource reference, @export, obj.name access, string literal, addon, class_name, fortressgd:keep) with the file responsible. Needs no secret. --json for the full report, --all for every name. |
verify |
List packed paths; fail on leaked excludes, shipped .pdb files or source maps next to the artifact, shaders that still contain comments, unencrypted bodies in an encrypted pack, leftover debug tables, or bad signatures. |
Exit codes: 0 ok, 1 config/user error, 2 verify/policy failure, 3 tool or engine build failure. Errors print error: … and Run: <next command>.
Examples
Section titled “Examples”# Check the project is wired correctlyfortressgd doctor
# Secret from CI, not a local fileFORTRESSGD_SECRET="$SECRET_FROM_CI" fortressgd secret status
# Build both platforms from toml [platforms].buildfortressgd templates build --godot 4.6.2
# See what is already cachedfortressgd templates list# godot-4.6.2-template_release-linux-x86_64-fgd…………-………………
# Export a named preset from export_presets.cfgfortressgd export --preset "Linux"fortressgd export --preset "Windows Desktop"
# Verify an embedded PCK inside an exefortressgd verify build/my_game.x86_64Godot binary resolution for export: FORTRESSGD_GODOT, then GODOT, then GODOT_BIN, then godot / godot4 on PATH. With dialect = true, FORTRESSGD_EDITOR comes first, then the cached export editor (on Linux), then the same list. That editor runs with its own Godot cache under <cache_dir>/editor-cache/, so it never shares one with your own Godot editor.
Editor plugin
Section titled “Editor plugin”fortressgd init copies addons/fortressgd and enables it in project.godot. The release filters only run while it is enabled, so fortressgd export refuses to run if it is turned off, and fortressgd doctor warns. Run fortressgd init again, or re-enable it in Project → Project Settings → Plugins.
On presets tagged fortressgd_production the export plugin:
- Skips forced-exclude paths (unless allowlisted)
- Optionally mangles GDScript before bytecode remap
- Restores original scripts after export
- Writes the source map to
.fortressgd/maps/in the project (mirroring the export path), never next to the artifact
It never compiles the engine and never writes the raw secret into export_presets.cfg. If you export from the editor without FortressGD templates, use fortressgd export (or build templates first) for encrypted / dialect packs.
Build templates once per (godot version, patchset, secret hash, platform) and cache them. Pin the action and the CLI to the same release:
- uses: actions/setup-python@v5 with: python-version: "3.12"- run: pip install "fortressgd @ https://github.com/salaryman-inc/FortressGD/releases/download/v0.2.0/fortressgd-0.2.0-py3-none-any.whl"
- uses: salaryman-inc/FortressGD/actions/build-templates@v0.2.0 with: godot_version: "4.6.2" platforms: "linux,windows" secret: ${{ secrets.FORTRESSGD_SECRET }}
- run: fortressgd export --preset Linux env: FORTRESSGD_SECRET: ${{ secrets.FORTRESSGD_SECRET }}- run: fortressgd verify path/to/your_game.pck env: FORTRESSGD_SECRET: ${{ secrets.FORTRESSGD_SECRET }}Cache key: fgd-templates-{godot}-{patchset}-{secret_hash}-g{generator}-{platforms}-e{key_epoch}[-sig]. Pass key_epoch to the Action when the project sets [production].key_epoch. At a release tag, the Action downloads the release’s images.lock.json, checks its provenance with gh attestation verify and relinks in the pinned build images. The secret never enters the build container: templates build writes fortressgd_gen.cpp (the encoded pack key and public values) on the host and passes only that file and the public secret_hash to Docker.
The weekly end-to-end workflow (.github/workflows/e2e.yml) builds real templates, exports the sample project, and runs a pinned KeyDot version against the protected Windows build; KeyDot failing to recover the key or project is a pass. Locally the same test is opt-in (FORTRESSGD_UNPACKER_TESTS=1). The same workflow runs the latest GDRE Tools release with --recover on the protected Linux builds, with and without the dialect, and fails if any script contents come back, and checks that a sign_packs template refuses unsigned and tampered packs. Its cross-build check builds the sample project with two secrets and at two key epochs, and checks that an extractor written for one build fails on the others (DESIGN.md §18.7). gdke and GodotPCKExplorer are not tested yet, so the claim that they fail rests on design reasoning, not on a test run. See docs/ci.md.
Repository layout
Section titled “Repository layout”DESIGN.md source of truth for implementersTHREAT_MODEL.md short threat modelbin/fortressgd run the CLI from a checkoutfortressgd/ the Python package (everything below ships in the wheel) cli/ fortressgd CLI core/ shared library generator/ writes fortressgd_gen.cpp, the per-build code (build artifact, not committed) plugin/addons/fortressgd/ editor plugin, copied by `fortressgd init` patches/<godot-tag>/ quilt applied to a pinned upstream tag docker/ toolchain and build image Dockerfiles fortressgd.example.toml config written by `fortressgd init`actions/build-templates/ CI template factory.github/workflows/ CI for this repotestdata/ sample project + unpacker fixturestests/ test suitedocs/ getting-started, CI, secrets, agent rules + the docs siteThere is no Godot source tree in this repo. A tag without fortressgd/patches/<tag>/series is unsupported.
Tests: python3 tests/run.py. See CONTRIBUTING.md.
Comparison
Section titled “Comparison”| Official encrypt | Godot-Secure | GDMaim | ChaosProtector | FortressGD | |
|---|---|---|---|---|---|
| Stock KeyDot/GDRE | Usually succeed (KeyDot reads Windows and Web builds) | Project claims fail | Pack opens; scripts are obfuscated | Vendor claims fail (Windows x86-64) | Target: fail (KeyDot and latest GDRE checked by the e2e workflow) |
| Editor | Official + custom templates | Patched editor | Official (4.5+) | Official | Official |
| Source leaks | Your problem | Your problem | Your problem (strips comments only) | Not advertised | verify fails the build |
| Script names | Intact | Intact (token IDs optionally scrambled) | Identifiers mangled; file paths intact | Not advertised | Optional mangler |
| You compile Godot how? | By hand | By hand (in-place patch script) | No | No (post-build tool) | Dialect templates: no, a prebuilt build image relinks them. The export editor (once per Godot tag) and dialect-off templates: in Docker / Action |
| License | MIT engine | MIT | MIT | Commercial, closed source (free tier) | MIT |
Third-party columns summarize each project’s own documentation as of November 2026; claims marked “claims” are the project’s own and were not tested by FortressGD. Corrections are welcome.
All of these are also published as a website: https://fortressgd.salaryman.com/
docs/getting-started.md— leak checks with the official editordocs/ci.md— template factory, build images, build times, unpacker fixturesdocs/releasing.md— what a release publishes, verifying it, cutting onedocs/secrets.md— where to keep the secret, whatdoctorchecks, rotation runbookdocs/agent-rules.md— Callables vs stringcall/rpc, no secrets underres://DESIGN.md— normative specTHREAT_MODEL.md— in-scope vs out-of-scope attacksSECURITY.md— how to report a vulnerability or a bypassCONTRIBUTING.md— development setup, tests, project rules
When implementing or changing behavior: do not add packers, VMs, anti-debug, or license servers; do not vendor Godot source; fail export rather than ship a recoverable or broken build; update DESIGN.md in the same change if behavior shifts.
License
Section titled “License”MIT.