Contributing

Branch and commit conventions, the fix-forward rule, the security posture, and the PR checklist.

Contributing

HostSSH has a small number of hard conventions. They exist because the platform hosts real customer data — the bar is production-grade, not prototype.


Commits

Conventional commits, lower-case type(scope): imperative subject, often with a trailing context tag like (Gate A P0):

feat(agent): default HOSTNAME=0.0.0.0 for web apps (G1)
fix(platform): keep cancelled jobs terminal
docs(dev): add the deploy pipeline internals

Types in use: feat, fix, docs, chore, refactor. Scopes in use: agent, control-plane, platform, deploy, dns, alerts, fleet, migrate, security, backup, firewall, wp-migrate, guards, planning, ops.

Rules:

  • Atomic commits — one logical change each.
  • NEVER add Co-Authored-By or any AI attribution. This is a hard project rule.
  • Never commit secrets — no keys, tokens, or credentials. CI runs gitleaks and a hygiene scan.
  • Stage explicit paths; don't git add -A (you'll catch node_modules, .next, build caches).

Branches

feat/<kebab-name> (e.g. feat/security-hardening-baseline). Branch off main; open a PR into main. Don't commit or push to main directly.


The fix-forward rule (most important)

Every bug fix lands at the most upstream layer that makes it automatic for every app, plus a regression test, plus a catalog entry:

  1. Fix in the agent defaults / deploy pipeline / shared template — not on one box or one app.
  2. Add a *_test.go / *.test.ts that fails before your fix and passes after.
  3. Append a row to planning/BUILD-GUARDS.md.
  4. If it's a class of failure that could reach production, wire it into the checks gate.

A fix that lives on one server is a bug waiting to reappear. See Build guards.


Zero-dependency agent

agent/go.mod has no require block, and it stays that way. The agent is one auditable binary. Use the standard library, or shell out to system tools (docker, restic, nftables, cloudflared). CI's license gate rejects forbidden/restricted dependencies in both the agent and the control plane.


Security posture for changes

Some changes are ask-first — get explicit sign-off before implementing:

  • Auth / authz changes (RBAC, sessions, WebAuthn, RLS role model).
  • Anything that changes live DB ownership/roles (scripts/setup-db-roles.sql).
  • Cloudflare tunnel/DNS behavior and other outward-facing infra.
  • Destructive operations on a box (wipes, restores over live data) — these are owner-gated and never auto-run from the build loop.

Prove security-sensitive changes adversarially: a feature that touches secrets, tenancy, or the agent↔control-plane channel isn't done until someone tries to break it. See Security model.


Evidence in the PR

A PR carries the proof, not just the claim:

  • The verification command output (go test ./... -race, npm run lint && typecheck && test && build).
  • For deploy/backup/security changes touching a real box, the captured evidence (curl output, monitor state, snapshot ids) — "evidence or it didn't happen."
  • Updated planning/TODO.md checkboxes and, where relevant, the build-guards catalog.

PR checklist

  • Conventional commit(s), no AI attribution, atomic, explicit paths staged.
  • Fix landed upstream (not per-box) + regression test added.
  • Build-guards catalog updated if a bug class was fixed.
  • Agent: gofmt -l . clean, go build/vet/test ./... -race green, no new deps.
  • Control plane: lint, typecheck, test, build green.
  • Migrations (if any): next number, appended to list.ts, list.test.ts passes, no shipped migration edited.
  • No secrets committed; gitleaks/hygiene clean.
  • Security-sensitive change signed off (ask-first list above).
  • planning/TODO.md updated.
  • Verification output pasted into the PR.

The planning source of truth

planning/ is authoritative for what's built and what's next:

  • MIGRATION-MASTER-PLAN.md — the whole program, sequenced.
  • TODO.md — the task board with acceptance criteria.
  • BUILD-GUARDS.md — the fix-forward catalog.
  • GAP-REGISTER-2026-07-01.md — the audited backlog.

Read the plan before writing code; update it after.