How Canon assesses a repository
Canon reads a repository the way any visitor can, pins the result to the commit it read, and publishes every control it evaluated — including the ones it could not judge. This page states the whole method: the 132 controls, the score formula, the alternative mechanisms Canon accepts as evidence, and what a public reader is never able to see.
How the score is calculated
Every control ends in one of four outcomes. Only the first two are scored.
- Confirmed
- Canon read the evidence and the practice is in place. Counts in the numerator and the denominator.
- Gap
- Canon read the location and the evidence is absent. Counts in the denominator only.
- Not applicable
- The control does not apply to this repository — no database, no containers, no deployment. Excluded entirely.
- Not assessable
- The evidence needs access a public reader never has, or a read failed. Reported, never counted against the repository.
- The denominator contains only controls that are both applicable and assessable from what Canon could read. A repository is never penalised for a setting it did not choose to hide.
- A partially met control counts as half a confirmation.
- Optional practices are reported but never scored — a repository that chooses not to adopt one has not failed a control. Currently optional: SC-09.
- Each result is pinned to the commit it was assessed at, so two scores are only comparable against the commits they name.
What a public reader can and cannot see
Of the 132 controls, 76 are answerable from files and metadata anyone can read. The remaining 56 depend on settings only a repository administrator can retrieve. On these public pages those controls are marked not assessable and left out of the score — not marked as failures.
Read from public evidence
The file tree at the assessed commit, workflow definitions, community health files in the repository root, .github/ or docs/, review-routing files, and the public rulesets endpoint, which reports whether a ruleset covers the default branch and how many approvals it requires.
Requires administration access
Branch-protection detail, code and secret scanning configuration, Actions permissions, environment reviewers, and organization membership. Connecting your own repository to Canon answers these as well; a public assessment cannot.
Equivalent mechanisms
A control asks whether a practice exists, not whether it is implemented the way GitHub documents it. Canon accepts these alternatives as evidence of the same control.
| The control asks for | Also accepted |
|---|---|
| CODEOWNERS routing review to named owners | Per-directory OWNERS files and Prow/TIDE review automation, including the approvers and reviewers they name |
| A protected default branch | A repository ruleset covering the default branch, read from the public rulesets endpoint, as well as classic branch protection |
| A human approval gate | A required-approvals count declared by a public ruleset, where no administration snapshot is available |
| Community health files | The repository root, .github/, .gitlab/ and docs/, matched case-insensitively — LICENSE, LICENCE and COPYING are the same control |
| A pinned toolchain version | .nvmrc, .node-version, .tool-versions, .python-version, runtime.txt, rust-toolchain, .ruby-version or go.mod |
| A named tool — linter, scanner, error tracker | Any tool of the same class configured in the repository or called from a workflow; the control is the practice, not the vendor |
The control list (132)
Grouped into the eight areas the heatmap and every case study use.
Governance
12 controls
Repository governance
| ID | Control | What Canon looks for | Severity | Applies to | Read from |
|---|---|---|---|---|---|
| CG-03 | Default branch protected by ruleset | A ruleset covers the default branch. | critical | Every repository | Repository administration |
| CG-05 | Pull-request requirement on default branch | PRs are required to the default branch. | critical | Every repository | Repository administration |
| CG-01 | Default branch identified | Named default branch exists. | high | Every repository | Public files |
| CG-04 | Force-push restricted | Force-push is blocked on protected branches. | high | Every repository | Repository administration |
| CG-06 | Administrator bypass restricted | Admin bypass is documented or disabled. | high | Every repository | Repository administration |
| CG-09 | Tag protection | Release tags cannot be rewritten. | high | Every repository | Repository administration |
| CG-02 | Branch strategy observable | A recognizable branching model exists. | medium | Every repository | Public files |
| CG-07 | GitHub App bypass inventory | Apps that can bypass protection are named. | medium | Every repository | Repository administration |
| CG-08 | Signed commits required | Commits to the default branch are signed. | medium | Every repository | Repository administration |
| CG-10 | Branch deletion protected | Protected branches cannot be deleted. | medium | Every repository | Repository administration |
| CG-11 | Linear history or documented merge method | Allowed merge methods are explicit. | low | Every repository | Repository administration |
| CG-12 | Visibility and ownership recorded | Repository identity is bound. | low | Every repository | Public files |
Review
26 controls
Change intake, pull requests and ownership
| ID | Control | What Canon looks for | Severity | Applies to | Read from |
|---|---|---|---|---|---|
| PR-01 | Required reviews | At least one approval is required. | critical | Every repository | Repository administration |
| OW-03 | Production approvers named | Production reviewers are resolved people or teams. | critical | Repositories that deploy | Environments |
| IN-04 | CODEOWNERS or review assignment | Reviewers can be resolved. | high | Every repository | Public files |
| PR-02 | CODEOWNERS reviews required | Code-owner review is required. | high | Repositories with declared ownership | Repository administration |
| PR-03 | Stale reviews dismissed | New pushes dismiss prior approvals. | high | Every repository | Repository administration |
| PR-04 | Last-push approval required | The last pusher cannot self-approve. | high | Every repository | Repository administration |
| PR-10 | Self-merge restricted | Authors cannot merge unreviewed work. | high | Every repository | Repository administration |
| OW-01 | CODEOWNERS or OWNERS file | A CODEOWNERS or per-directory OWNERS file exists. | high | Every repository | Public files |
| OW-02 | Owners resolve to principals | CODEOWNERS entries resolve. | high | Repositories with declared ownership | Organization members |
| OW-04 | Bypass actors justified | Every bypass actor is listed. | high | Every repository | Repository administration |
| IN-01 | Work arrives through a tracked path | Issues or templates exist for intake. | medium | Every repository | Public files |
| IN-02 | PR template present | A pull-request template exists.Looks at pull_request_template.md in the repository root, .github/ or docs/. | medium | Every repository | Public files |
| IN-06 | Security policy | SECURITY.md exists.Looks at SECURITY.md in the repository root, .github/ or docs/. | medium | Every repository | Public files |
| PR-05 | Conversation resolution required | Open threads block merge. | medium | Every repository | Repository administration |
| PR-06 | Review history inspectable | PR review APIs are readable. | medium | Every repository | Repository administration |
| PR-09 | Merge queue or serialized merge | Merges to main are serialized if required. | medium | Every repository | Repository administration |
| OW-05 | Team review path | Org teams can be resolved. | medium | Every repository | Organization members |
| OW-07 | On-call or incident owner | An incident owner is named.Looks at on-call, incident or escalation documents in the root, .github/ or docs/. | medium | Every repository | Public files |
| OW-08 | Secret custodians | Secret accessors are known. | medium | Every repository | Repository administration |
| IN-03 | Issue templates present | Issue templates exist.Looks at .github/ISSUE_TEMPLATE/ and .github/issue_template.md. | low | Every repository | Public files |
| IN-05 | Contributing guide | CONTRIBUTING exists.Looks at CONTRIBUTING.md in the repository root, .github/ or docs/. | low | Every repository | Public files |
| IN-07 | License declared | LICENSE exists.Looks at LICENSE, LICENCE or COPYING in the repository root, .github/ or docs/. | low | Every repository | Public files |
| IN-08 | Support or contact path | Support contact is documented. | low | Every repository | Public files |
| PR-07 | Linked issue or ticket | PRs can be traced to intake.Looks at the pull-request template, which is where intake links are asked for. | low | Every repository | Public files |
| PR-08 | Draft PR workflow documented | Draft vs ready is defined. | low | Every repository | Public files |
| OW-06 | Maintainer roster | Maintainers are documented. | low | Every repository | Public files |
CI & tests
30 controls
CI architecture, build reproducibility, testing
| ID | Control | What Canon looks for | Severity | Applies to | Read from |
|---|---|---|---|---|---|
| CI-01 | Workflows exist | GitHub Actions workflows exist. | critical | Every repository | Public files |
| CI-03 | Required checks match workflow names | Required check names resolve to runs. | critical | Repositories with CI workflows | Repository administration |
| TS-01 | Unit test command | A test script exists. | critical | Node.js repositories | Public files |
| TS-02 | Tests run in CI | CI invokes tests. | critical | Repositories with CI workflows | Public files |
| CI-02 | PR workflow trigger | CI runs on pull requests. | high | Repositories with CI workflows | Public files |
| CI-04 | Workflow permissions least-privilege | Workflows request contents: read unless they must write. | high | Repositories with CI workflows | Actions settings |
| CI-07 | Reusable workflows or action pins | Third-party actions are pinned.Looks at the workflow files, for reusable workflow calls and SHA-pinned actions. | high | Repositories with CI workflows | Public files |
| CI-10 | Required status checks strict | Branch must be up to date with checks. | high | Repositories with CI workflows | Repository administration |
| BL-01 | Lockfile present | A lockfile exists. | high | Node.js repositories | Public files |
| BL-04 | Build command defined | A build script exists. | high | Node.js repositories | Public files |
| TS-05 | Required check includes tests | The test job is required. | high | Repositories with CI workflows | Repository administration |
| CI-05 | Actions run history readable | Workflow runs can be listed. | medium | Repositories with CI workflows | Actions settings |
| CI-06 | Check runs readable | Check runs can be listed. | medium | Repositories with CI workflows | Actions settings |
| CI-09 | Separate CI from deploy | Deploy is not implicit in every CI job. | medium | Repositories that deploy | Public files |
| CI-11 | Workflow not skippable by path ignore on critical files | Critical paths still run CI. | medium | Repositories with CI workflows | Public files |
| BL-02 | Pinned runtime | Node or runtime version is pinned.Looks at .nvmrc, .node-version, .tool-versions, .python-version, runtime.txt, go.mod. | medium | Node.js repositories | Public files |
| BL-03 | Deterministic install command | Install is frozen. | medium | Node.js repositories | Public files |
| BL-06 | Container build definition | Dockerfile or compose exists.Looks at Dockerfile and docker-compose files anywhere in the tree. | medium | Repositories with containers | Public files |
| BL-08 | Provenance or attestations | Build provenance is produced. | medium | Repositories with CI workflows | Actions settings |
| TS-03 | Typecheck command | Typecheck exists if typed. | medium | Node.js repositories | Public files |
| TS-04 | E2E or integration tests | Broader tests exist when claimed. | medium | Node.js repositories | Public files |
| TS-08 | Contract or API tests | Interface changes are tested.Looks at contract or API test files and an OpenAPI description. | medium | Repositories that deploy | Public files |
| TS-09 | Migration tests | Schema changes are tested.Looks at test files that exercise migrations. | medium | Repositories with a database | Public files |
| TS-10 | Preview validation | Previews are exercised.Looks at preview, smoke and end-to-end workflows. | medium | Repositories that deploy | Public files |
| CI-08 | Concurrency cancellation | Stale runs cancel.Looks at the workflow files, for a concurrency group. | low | Repositories with CI workflows | Public files |
| CI-12 | Manual workflow_dispatch documented | Manual runs are intentional. | low | Repositories with CI workflows | Public files |
| BL-05 | No unchecked generated artifacts | Build output is not the source of truth. | low | Every repository | Public files |
| BL-07 | Cache keyed and scoped | CI caches are explicit. | low | Repositories with CI workflows | Public files |
| TS-06 | Flaky-test policy | Retries are bounded. | low | Repositories with tests | Public files |
| TS-07 | Coverage gate | Coverage is tracked if claimed.Looks at coverage configuration and the coverage steps in CI. | low | Repositories with tests | Public files |
Code quality
8 controls
Code quality
| ID | Control | What Canon looks for | Severity | Applies to | Read from |
|---|---|---|---|---|---|
| CQ-01 | Lint command | Lint exists. | medium | Node.js repositories | Public files |
| CQ-02 | Lint runs in CI | CI lints. | medium | Repositories with CI workflows | Public files |
| CQ-04 | Required lint check | Lint is a required check. | medium | Repositories with CI workflows | Repository administration |
| CQ-05 | Static analysis beyond lint | SAST or equivalent runs. | medium | Every repository | Security settings |
| CQ-08 | Dependency review on PRs | New dependencies are reviewed. | medium | Repositories with CI workflows | Security settings |
| CQ-03 | Formatter agreed | Format tool is present.Looks at formatter configuration (Prettier, Biome, rustfmt, clang-format, ruff). | low | Node.js repositories | Public files |
| CQ-06 | Secret patterns in lint | Secrets are not committed.Looks at secret-detection configuration and secret-scanning jobs in CI. | low | Node.js repositories | Public files |
| CQ-07 | EditorConfig or language style | Style is encoded.Looks at .editorconfig and .gitattributes. | low | Every repository | Public files |
Security
20 controls
Application security and software supply chain
| ID | Control | What Canon looks for | Severity | Applies to | Read from |
|---|---|---|---|---|---|
| AS-01 | Code scanning configured | Code scanning runs. | high | Every repository | Security settings |
| AS-02 | Push protection enabled | Secret push protection is on. | high | Every repository | Security settings |
| AS-03 | Dependabot alerts | Dependency alerts exist. | high | Every repository | Security settings |
| AS-04 | Secret scanning alerts | Secret scanning is on. | high | Every repository | Security settings |
| AS-07 | Default workflow token read-only | Default GITHUB_TOKEN is read. | high | Repositories with CI workflows | Actions settings |
| AS-09 | Environment secrets not in repo files | No committed credentials observed. | high | Every repository | Public files |
| AS-10 | SAST required on default branch | Security jobs are required checks. | high | Every repository | Repository administration |
| SC-01 | Dependency lockfile | Dependencies are locked. | high | Node.js repositories | Public files |
| SC-02 | Actions from trusted sources | Third-party actions are allowlisted. | high | Repositories with CI workflows | Repository administration |
| SC-03 | Action SHA pins | Actions are pinned by digest.Looks at every `uses:` reference in the workflow files. | high | Repositories with CI workflows | Public files |
| AS-05 | Security policy | SECURITY.md exists.Looks at SECURITY.md in the repository root, .github/ or docs/. | medium | Every repository | Public files |
| AS-08 | Fork PR secrets isolated | Fork PRs cannot steal secrets. | medium | Repositories with CI workflows | Actions settings |
| SC-04 | Package provenance | Published packages have provenance.Looks at the release workflows, for provenance or attestation steps. | medium | Node.js repositories | Public files |
| SC-05 | SBOM or dependency graph | Dependency graph is enabled. | medium | Every repository | Security settings |
| SC-06 | No mutable tags for release artifacts | Release tags are immutable. | medium | Every repository | Repository administration |
| SC-07 | Artifact attestation | Release artifacts are attested. | medium | Repositories with CI workflows | Actions settings |
| SC-10 | Review of high-risk dependency changes | Lockfile changes get extra review. | medium | Repositories with CI workflows | Public files |
| AS-06 | Private vulnerability reporting | Private reporting is enabled. | low | Every repository | Repository administration |
| SC-08 | Private package registry auth | Registry auth is not in git. | low | Node.js repositories | Public files |
| SC-09 | Dependabot version updatesOptional — not scored | Automated updates exist if desired. | low | Every repository | Public files |
Agents & AI
8 controls
AI and agentic development
| ID | Control | What Canon looks for | Severity | Applies to | Read from |
|---|---|---|---|---|---|
| AI-03 | Human gate before merge | Agent PRs still need human approval. | critical | Repositories using coding agents | Repository administration |
| AI-02 | Agent write paths constrained | Agents cannot write production unattended. | high | Repositories using coding agents | Public files |
| AI-05 | Prompt or tool secrets not in repo | Agent secrets are not committed. | high | Repositories using coding agents | Public files |
| AI-06 | Agent workflow permissions | Agent workflows are least-privilege. | high | Repositories using coding agents | Public files |
| AI-01 | Agent artifacts detected | Agent definitions are inventoried. | medium | Every repository | Public files |
| AI-04 | Agent identity in commits | Agent authorship is visible. | medium | Repositories using coding agents | Beyond a public snapshot |
| AI-07 | Audit of agent actions | Agent runs are retained. | medium | Repositories using coding agents | Actions settings |
| AI-08 | Fallback when agent fails | A human path exists if the agent fails. | medium | Repositories using coding agents | Public files |
Release & ops
22 controls
Deployment, databases and observability
| ID | Control | What Canon looks for | Severity | Applies to | Read from |
|---|---|---|---|---|---|
| DP-02 | Production protection | Production has protection rules. | critical | Repositories that deploy | Environments |
| DP-03 | Production reviewers resolved | Reviewers are real principals. | critical | Repositories that deploy | Environments |
| DB-03 | No unattended prod migration | Prod migrations need approval. | critical | Repositories with a database | Environments |
| DP-01 | Environments defined | Environments exist when you deploy. | high | Every repository | Environments |
| DP-04 | OIDC instead of long-lived keys | Deploy jobs use OIDC. | high | Repositories that deploy | Actions settings |
| DP-10 | Environment secrets scoped | Secrets are environment-scoped. | high | Repositories that deploy | Repository administration |
| DB-01 | Migration files exist | Migrations live in the repo. | high | Repositories with a database | Public files |
| DB-02 | Migrations reviewed | Migrations follow the PR path. | high | Repositories with a database | Public files |
| DP-05 | Deployment history readable | Deployments can be listed. | medium | Repositories that deploy | Environments |
| DP-07 | Preview distinct from production | Preview and production are separate. | medium | Repositories that deploy | Public files |
| DP-08 | Rollback path | Rollback is documented.Looks at rollback or recovery documents in the root, .github/ or docs/. | medium | Repositories that deploy | Public files |
| DP-09 | Release workflow separate | Release is an explicit workflow. | medium | Repositories with CI workflows | Public files |
| DB-04 | Backup or restore note | Restore is documented.Looks at backup or restore documents in the root, .github/ or docs/. | medium | Repositories with a database | Public files |
| DB-05 | Schema change tests | Migrations are tested.Looks at test files that exercise migrations. | medium | Repositories with a database | Public files |
| OB-01 | Health check or status | Health endpoints exist.Looks at health or status endpoints and container health checks. | medium | Repositories that deploy | Public files |
| OB-04 | On-call runbook | A runbook exists.Looks at runbook or operations documents in the root, .github/ or docs/. | medium | Repositories that deploy | Public files |
| OB-06 | Audit of privileged actions | Admin actions are attributable. | medium | Every repository | Repository administration |
| DP-06 | Wait timer or freeze window | Production changes can be delayed. | low | Repositories that deploy | Environments |
| DB-06 | Expand/contract documented | Breaking schema changes are staged. | low | Repositories with a database | Public files |
| OB-02 | Logging approach documented | Logging is described. | low | Every repository | Public files |
| OB-03 | Error tracking referenced | Sentry or equivalent is referenced.Looks at error-tracking configuration (Sentry, Bugsnag, Rollbar, Datadog). | low | Repositories that deploy | Public files |
| OB-05 | Release annotations | Releases can be correlated.Looks at the changelog, .changeset/ and release automation configuration. | low | Repositories that deploy | Public files |
Docs
6 controls
Documentation
| ID | Control | What Canon looks for | Severity | Applies to | Read from |
|---|---|---|---|---|---|
| DC-01 | README present | README exists. | medium | Every repository | Public files |
| DC-04 | Threat or trust notes for agents | Agent trust boundaries are written.Looks at agent trust-boundary or threat notes in the root or docs/. | medium | Repositories using coding agents | Public files |
| DC-02 | Architecture or system notes | System shape is described. | low | Every repository | Public files |
| DC-03 | Local development instructions | Dev setup is documented. | low | Every repository | Public files |
| DC-05 | Changelog or release notes | Releases are described.Looks at CHANGELOG.md in the repository root, .github/ or docs/. | low | Every repository | Public files |
| DC-06 | Inspect notes captured | Discovery notes are retained. | low | Every repository | Public files |
Run this on your own repository
Connect a repository and Canon runs the same 132 controls, plus the 56 that need administration access. Your results stay private to your organization.
