This policy governs how changes to Cadence software, infrastructure, and configuration are reviewed, approved, tested, deployed, and documented to ensure stability, security, and auditability.
1. Purpose and Scope
All changes to Cadence production systems — including application code, database schema, server configuration, third-party integrations, and infrastructure — are subject to this policy. The goal is to prevent unauthorized or untested changes from impacting service availability or security.
2. Change Categories
| Category | Description | Approval Required | Testing Required |
| Standard | Routine, pre-approved, low-risk (e.g., minor UI updates, bug fixes) | Self-approval with documentation | Local validation |
| Normal | New features, schema migrations, third-party integrations | Security Officer review | Staging/test instance |
| Emergency | Critical security patch or outage recovery | Post-deployment documentation within 24 hours | Minimal viable test, then full regression |
| Major | Architecture changes, new vendor onboarding, new data types | Written risk assessment + Security Officer approval | Full test suite + staged rollout |
3. Change Process
- Request: Document the change — what, why, affected systems, rollback plan
- Assessment: Classify the change (Standard/Normal/Emergency/Major); identify security/compliance impact
- Testing: Test on a non-production test instance or local environment
- Automated checks: Every change must pass CI (PHP syntax lint + Semgrep SAST) before being considered ready to deploy — an automated compensating control given the absence of a second-reviewer approval step (see Section 8)
- Approval: Obtain required approval based on change category
- Deployment: Deploy using
deploy.sh script; run migrations with deploy.sh migrate
- Verification: Confirm deployment succeeded; verify key user flows work
- Documentation: Record the change in git commit history with descriptive message
4. Database Schema Changes
- All schema changes must be implemented as numbered migration files (e.g.,
0120_feature.sql)
- Migrations must be idempotent where possible (use
IF NOT EXISTS, INSERT IGNORE)
- Migrations run automatically via
deploy.sh migrate which tracks applied migrations in the migrations table
- Rollback procedure for schema changes must be documented before deployment
5. Rollback Procedures
- All deployments use git-tracked files; rollback to prior version by re-deploying previous commit
- Database rollbacks require manual reversal script (document before deploying forward migration)
- Maintain daily encrypted backups in Backblaze B2 for point-in-time recovery
- Emergency rollback: stop SWAG container, restore backup, redeploy prior code version
6. Version Control Requirements
- All code changes tracked in GitHub repository (mrjacobarussell/mih-scheduler)
- Each PHP file carries an independent
@version tag bumped on every edit
- Commit messages must describe the purpose of the change (not just what changed)
- Production deployments are performed via
./deploy.sh from the git working directory
7. Emergency Changes
In the event of an active security incident or critical outage, changes may be deployed immediately. The following must be completed within 24 hours of the emergency change:
- Document what was changed and why
- Record the change in git with an emergency change commit message
- Conduct a brief post-change review to confirm the fix resolved the issue without introducing new risk
- Update the incident response log if the change was related to a security incident
8. Review Gate — Compensating Controls for a Single-Engineer Team (added July 2026, revised July 16, 2026)
Cadence is developed by a single-person engineering team, so a traditional "second-person PR approval" control does not apply — there is no second engineer to approve anything. This section documents the compensating controls actually in place instead of leaving the review step undocumented:
- Direct-to-main commits, by design: Changes are committed directly to the main branch, not routed through feature branches and pull requests. This is a deliberate choice, not an oversight — see the Enforcement Decision below.
- Automated CI on every push: PHP syntax linting, Semgrep SAST, and Trivy CVE scanning run on every push via GitHub Actions, surfacing problems immediately after they land.
- Test-instance-first discipline: Per Section 3, risky changes (schema alterations, permission changes, anything touching PHI-handling code) are verified on a non-production test instance before being applied to any production instance — this is the primary functional check standing in for a second reviewer's sign-off, and the control actually relied on day-to-day.
- Enforcement decision (2026-07-16): GitHub branch protection (requiring CI to pass before merge) is available on this private repository and was deliberately not enabled. Branch protection's merge-gate only has teeth if changes go through a pull request rather than a direct push — adopting it would mean routing every change, however small, through a branch and PR for a team of one, solely to satisfy a checkbox, with no second reviewer ever actually looking at the diff. The real safety net remains test-instance-first verification, which does not depend on this workflow change. Revisit if the team grows beyond one engineer.
Security Officer Signature
Jacob Russell — Security Officer, EMStool LLC
Date Reviewed
June 29, 2026