5.1 KiB
Development conventions
Language and style
- Documentation and stable identifiers are English-first; UI strings are localizable from the start.
- Use idiomatic current stable Go, explicit errors and small interfaces at consumer boundaries.
- Prefer server-rendered
html/templateviews, progressive enhancement and small focused browser modules; do not introduce a large SPA framework without an accepted architectural reason. - Format and lint frontend and Go code with repository-pinned tools.
- Avoid hidden global state. Inject clock, ID generator and external interfaces for deterministic tests.
- Use UTC internally and IANA timezones at scheduling boundaries.
Repository shape
The implementation may refine this layout while preserving boundaries:
cmd/dogama/
cmd/dogama-agent/
internal/ non-public Go packages
web/ embedded UI source
migrations/ append-only SQLite migrations
specs/ schemas and normalized contracts
catalog/ reference templates
modules/ reference modules and fixtures
docs/
tests/integration/
Initial application development
The initial main application requires Go 1.25. SQLite is provided by the pure-Go modernc.org/sqlite driver, so neither cgo nor a system SQLite development library is required. It reads only bootstrap settings from DOGAMA_LISTEN_ADDRESS (default :8080) and DOGAMA_DATABASE_PATH (default dogama.db). Run it with:
go run ./cmd/dogama
Browser sessions always use Secure, HttpOnly, and SameSite=Strict cookies. Place the application behind a trusted TLS reverse proxy for browser use, including development environments. The application does not accept forwarded client addresses as authoritative for authentication throttling.
The restricted agent is a separate binary:
go run ./cmd/dogama-agent
It fails closed unless DOGAMA_AGENT_TOKEN_FILE references a 32-byte-or-longer
secret and at least one of DOGAMA_ALLOWED_SERVER_ROOT or
DOGAMA_ALLOWED_BACKUP_ROOT is configured. Its bootstrap-only defaults are
:8081, /var/run/docker.sock and
/var/lib/dogama-agent/registry.json. The configured roots must already exist
and are canonicalized with symlinks resolved. For normal deployment, use the
secret file and private control network defined in compose.yaml; never publish
the agent port on the host.
At main-application startup, every embedded catalog/*/template.yaml is
validated against specs/template.schema.json, checked for cross-reference and
asset integrity, canonicalized deterministically and synchronized into SQLite.
An existing template ID/version is immutable: changing its digest fails startup
instead of silently replacing the snapshot. Deployment previews pin that digest
and redact secret defaults before a draft instance can enter the registry.
Contract changes
Template schema, manifest schema, normalized module API and agent deployment plan are versioned contracts.
- Backward-compatible additions do not change existing meanings.
- Breaking changes require a new schema/API major version and documented migration.
- Released examples are updated or retained as compatibility fixtures.
- Instances pin immutable versions; runtime behavior never depends on a mutable catalog file.
Testing pyramid
- Unit: domain policies, permission evaluation, cron/timezones, state transitions, retention and redaction.
- Property/fuzz: paths, archive entries, schema inputs, agent plans and normalized module payloads.
- Integration: SQLite migrations, disposable Docker agent, real archive workflows and WASM sandbox limits.
- End-to-end: bootstrap, Palworld dry/test fixture deployment, role views, backup/restore and update rollback.
Tests must include denial and interrupted-operation cases, not only happy paths. External game APIs use recorded or purpose-built fixtures in normal CI; live Palworld verification is a separate documented test.
Migrations and compatibility
Never rewrite a released migration. Migration execution is transactional where SQLite permits and creates a pre-migration database backup for release upgrades. Store application/schema version and test upgrade from the previous release.
Dependencies and supply chain
Prefer standard-library or mature focused dependencies. Pin build tooling, review transitive changes and generate an SBOM/reproducible checksums for releases. Do not dynamically download executable code at runtime except administrator-installed validated WASM packages.
Observability
Structured technical logs use stable event names and redaction. Metrics are operationally small. Correlation/operation IDs connect HTTP, job and agent errors without storing request secrets.
Review checklist
- Correct trust boundary and backend authorization?
- Can input influence a host path, Docker plan, URL or secret?
- Are retries/idempotency and restart recovery defined?
- Could failure delete or corrupt player data?
- Do documentation, schema and examples agree?
- Are UI capability checks backed by server checks?
- Are audit and notifications appropriately minimal?