SCOPE: everything in progressdocs/compliance/change-management-policy.md · build b00458d32828

Change management policy (draft)

Lucent Axis, SCOPE. Draft 28 Oct 2026. Owner: Dan. Approved by: [Kyle, on return]. Review: yearly. SOC 2 CC5.1, CC8.1, items SC-5, SC-6, ORG-07, TS-9, TS-11.

Scope

Every change to SCOPE's code, database schema, configuration of the hosting accounts (Vercel, Supabase, GitHub) and the add-ons. Content a user types into the app is not a change.

Code and schema

  1. Every change reaches main on lucent-axis/scope through a pull request. Nobody pushes to main directly; a ruleset enforces it (ORG-07, .github/rulesets/main.json), and scripts/git/ship.sh is the routine for getting a change there.
  2. The pull request uses the template (.github/pull_request_template.md): what changes, its risk, how it is undone, whether it could take the app down, and how it was tested.
  3. The required CI checks must pass before it merges. Exactly five are required, as the ruleset lists them: check, secrets, pre-commit, build and data. Between them they cover types, lint, tests, the build, secret scanning (gitleaks), the pre-commit guards and the data suites. Dependabot alerts and the dependencies and code-scan jobs also run, but are not required.
  4. Review. While one developer writes the code, a second approval before merging is not required. Instead the security owner reviews every pull request merged that month, within the first ten working days of the next, and records the review in the evidence log (control-calendar.md). A change rated High in the template is shown to the security owner before it merges where they are reachable, and is called out in the monthly review either way. When a second developer joins, one approval becomes required.
  5. Database migrations live in supabase/migrations/, are tested nightly against a fresh database built from every migration (after merge), and are applied to a client's database only by the release workflow, never from a laptop, once that workflow exists (SC-6). Until then, every manual supabase db push is written into the dashboard change log below.
  6. Production releases follow docs/internal/release-and-deploy-plan.md: staging first, live approved by a second person.

Segregation of duties

Two people run SCOPE, and one of them, the app owner, writes the code. So today one person can write a change, open its pull request, merge it, apply its migration and deploy it: the duties SOC 2 would like split across people are not split. This is stated rather than hidden. A second approval on every pull request would be the usual control, and with one developer it would mean the security owner approving code they did not write and cannot test, which records an approval without adding a check. Instead, these controls stand in for it:

What one person can do alone What catches it Where it shows
Push a change straight to main Nothing can: the ruleset refuses a direct push, owners included, with no bypass list .github/rulesets/main.json; GitHub's audit log for any time it is switched off (Emergencies, below)
Merge a change that breaks something The five required checks must pass first: types, lint, tests, build, secret scanning, the pre-commit guards, the data suites The checks on each pull request
Merge a change nobody else looked at The security owner reviews every pull request merged that month, within the first ten working days of the next; a High-risk change is shown to them before it merges where they are reachable The monthly review in the evidence log (control-calendar.md)
Change a setting in Vercel, Supabase or GitHub Every hand-made change goes in the dashboard change log the same day; the monthly review reads the log against the security baseline, so an unlogged change shows up as drift The log below; the monthly baseline file
Apply a migration to a client's database Only the release workflow applies one, never a laptop, once it exists (SC-6); until then every manual push is in the dashboard change log The workflow run, or the log
Put a release into a client's production deploy-release.yml refuses a production run by the person who put that release on staging, so production always takes two people The workflow's refusal; GitHub's Deployments page per environment

Nobody reviews their own work. Where the security owner made the change (a dashboard setting, a ruleset switch in an emergency), the platform owner reviews that line in the monthly review instead, and signs it.

When this ends. When a second developer joins, a pull request needs one approval from someone other than its author (the ruleset's required_approving_review_count goes to 1), and this section is rewritten. The risk is R16 in the risk register.

Emergencies

Nobody can bypass the ruleset on main, owners included. To stop an outage or a security incident, an organization owner may set the ruleset to Disabled, merge the fix, and set it back to Active; GitHub's audit log records both switches. Within one working day the owner adds a comment to the pull request saying why and how long the ruleset was off, and the monthly review covers it. The ruleset itself is kept as .github/rulesets/main.json, so a change to it is a reviewed change too.

Changes made in a dashboard

A change to Vercel, Supabase or GitHub settings made by hand (a setting switched, a member added, an environment variable changed, a database password rotated) is recorded the same day in the dashboard change log: date, who, what, why. The readiness and this-week documents record the Step 0 changes; from Step 0 onwards the log is this table.

Date Who System Change Why
2026-10-27 Kyle Vercel Created team lucent-axis, project scope-web, enforced MFA, connected Supabase Step 0 (OW-2, OW-3, ORG-06)
2026-10-28 Claude, approved by Dan GitHub Dependabot alerts on for lucent-axis/scope ORG-26
2026-10-28 Dan GitHub Ruleset main (id 26059181) applied to lucent-axis/scope from .github/rulesets/main.json ORG-07, SC-5
2026-10-28 Claude, approved by Dan Supabase (company project) Backed up; 10 pending migrations applied; personas add-on installed; grants restored after the copy reset them; demo passwords rotated; sessions cleared OW-3, OW-8
2026-10-28 Claude, approved by Dan Vercel (scope-web) Production NEXT_PUBLIC_DEMO_PASSWORD set to the rotated password OW-8

Separation of environments

Development happens on laptops and throwaway databases; demos on the demo project; each client on its own staging and production (ORG-11, VE-1). Real client data is never copied into a development or demo database.

Back to top