@keelcore/standards 0.9.7 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -26
- package/governance/ai/conduct.md +17 -26
- package/governance/api-management.md +91 -102
- package/governance/arb.md +55 -62
- package/governance/bash.md +117 -46
- package/governance/ci.md +165 -144
- package/governance/coding.md +89 -78
- package/governance/observability.md +77 -86
- package/governance/platform.md +81 -87
- package/governance/release-policy.md +126 -96
- package/governance/runtime.md +87 -95
- package/governance/security.md +77 -85
- package/governance/testing.md +66 -20
- package/package.json +1 -1
package/governance/runtime.md
CHANGED
|
@@ -1,154 +1,146 @@
|
|
|
1
1
|
# Runtime and Orchestration Standards
|
|
2
2
|
|
|
3
|
-
These rules govern container design, orchestration, deployment, and policy compliance.
|
|
4
|
-
|
|
3
|
+
These rules govern container design, orchestration, deployment, and policy compliance. They are non-negotiable unless
|
|
4
|
+
explicitly superseded by a signed ADR.
|
|
5
5
|
|
|
6
|
-
**Maturity:** Required
|
|
7
|
-
**Version:** 1.0.0
|
|
8
|
-
**Last Reviewed:** 2026-03-09
|
|
6
|
+
**Maturity:** Required **Version:** 1.0.0 **Last Reviewed:** 2026-03-09
|
|
9
7
|
|
|
10
8
|
## Containers and Artifacts
|
|
11
9
|
|
|
12
10
|
### Versioning
|
|
13
11
|
|
|
14
|
-
1. All published artifacts (container images, packages, binaries) use Semantic Versioning (SemVer).
|
|
15
|
-
|
|
16
|
-
2. The artifact tag is the SemVer string. The `latest` tag must not be used in staging or
|
|
17
|
-
production manifests.
|
|
12
|
+
1. All published artifacts (container images, packages, binaries) use Semantic Versioning (SemVer). Unversioned or
|
|
13
|
+
date-stamped-only artifacts are prohibited.
|
|
14
|
+
2. The artifact tag is the SemVer string. The `latest` tag must not be used in staging or production manifests.
|
|
18
15
|
|
|
19
16
|
### Container Design
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
and limited to ephemeral paths (`/tmp`, named volumes).
|
|
18
|
+
1. One process per container. Process supervisors (supervisord, s6) and multi-process containers are prohibited except
|
|
19
|
+
for sidecar patterns enforced by the service mesh.
|
|
20
|
+
2. Multiple entry points (different commands/args) for the same image are allowed where the image provides genuinely
|
|
21
|
+
distinct modes (e.g., `serve` and `migrate`). Each entry point must be documented in the image's README.
|
|
22
|
+
3. Containers run as a non-root user. `USER root` in the final image stage is prohibited.
|
|
23
|
+
4. Container filesystems are read-only where possible. Writable directories are explicitly declared and limited to
|
|
24
|
+
ephemeral paths (`/tmp`, named volumes).
|
|
29
25
|
|
|
30
26
|
### Artifact Metadata
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
1. Every artifact must embed: Git commit SHA, repository URL, branch, build timestamp, and SemVer. These are queryable
|
|
29
|
+
via a `version` subcommand or equivalent metadata endpoint.
|
|
30
|
+
2. Artifacts are tagged with: SemVer, commit SHA short form, and environment target (`dev`, `staging`, `prod`).
|
|
31
|
+
Promotion from one environment to the next reuses the same image digest — it is never rebuilt.
|
|
36
32
|
|
|
37
33
|
### Registry Lifecycle
|
|
38
34
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
1. Image promotion lifecycle: `dev` registry → `staging` registry → `prod` registry. Artifacts flow in one direction; no
|
|
36
|
+
artifact is pulled from `prod` into `dev`.
|
|
37
|
+
2. Artifacts not promoted to `staging` within 30 days of build are expired from the `dev` registry.
|
|
38
|
+
3. Artifacts in `prod` are retained for a minimum of 12 months.
|
|
43
39
|
|
|
44
40
|
### Security Scanning
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
1. CVE scanning runs on every artifact before it is pushed to any registry. The approved scanner is documented in the
|
|
43
|
+
internal vendor registry.
|
|
44
|
+
2. Critical CVEs block promotion. High CVEs require a documented exception with an accepted remediation timeline
|
|
45
|
+
(maximum 30 days). Medium and below are tracked but do not block promotion.
|
|
46
|
+
3. A Software Bill of Materials (SBOM) in SPDX or CycloneDX format is generated for every release artifact. The SBOM is
|
|
47
|
+
attached to the release and stored alongside the artifact digest.
|
|
52
48
|
|
|
53
49
|
## Orchestration
|
|
54
50
|
|
|
55
51
|
### Declarative Manifests
|
|
56
52
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
16. Manifests are validated (lint + schema check) as a required CI step before merge.
|
|
53
|
+
1. All workloads are declared via version-controlled orchestration manifests (Kubernetes YAML, Helm charts, Kustomize
|
|
54
|
+
overlays, or equivalent). Manual `kubectl apply` of locally generated YAML in production is prohibited.
|
|
55
|
+
2. Manifests are validated (lint + schema check) as a required CI step before merge.
|
|
61
56
|
|
|
62
57
|
### Probes
|
|
63
58
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
endpoints must not have side effects.
|
|
59
|
+
1. Every container that serves traffic must define `livenessProbe`, `readinessProbe`, and optionally `startupProbe`.
|
|
60
|
+
2. Readiness probes must reflect actual service readiness (e.g., database connection established, cache warm) not just
|
|
61
|
+
process startup.
|
|
62
|
+
3. Liveness probe failures must trigger a container restart, not a silent hang. Liveness probe endpoints must not have
|
|
63
|
+
side effects.
|
|
70
64
|
|
|
71
65
|
### Resource Quotas
|
|
72
66
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
67
|
+
1. Every workload declares `resources.requests` and `resources.limits` for CPU and memory. Pods without resource
|
|
68
|
+
declarations are rejected by admission control.
|
|
69
|
+
2. Resource requests must reflect measured steady-state usage. Over-requesting by more than 3× the p99 measured usage
|
|
70
|
+
requires justification.
|
|
71
|
+
3. Namespace-level `ResourceQuota` and `LimitRange` objects are applied to all tenant namespaces.
|
|
78
72
|
|
|
79
73
|
### High Availability
|
|
80
74
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
1. All production workloads run in a minimum of two availability zones. Single-zone deployments are prohibited in
|
|
76
|
+
production.
|
|
77
|
+
2. `PodAntiAffinity` rules are configured to prevent all replicas of a deployment from scheduling onto a single node or
|
|
78
|
+
zone.
|
|
79
|
+
3. Minimum replica count for production services is 2. Services with replica count 1 require documented justification
|
|
80
|
+
and ARB approval.
|
|
87
81
|
|
|
88
82
|
## Deployment
|
|
89
83
|
|
|
90
84
|
### Deployment Strategy
|
|
91
85
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
1. All production deployments use a rolling, blue/green, or canary strategy. Big-bang (recreate) deploys are prohibited
|
|
87
|
+
in production.
|
|
88
|
+
2. Deployments support rollback to the previous artifact version within 5 minutes.
|
|
89
|
+
3. Deployment events are logged in the audit log with: artifact version, deploy actor, environment, start time, end
|
|
90
|
+
time, and outcome.
|
|
97
91
|
|
|
98
92
|
### Zero-Downtime Deployment
|
|
99
93
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
94
|
+
1. Zero-downtime deployment capability is required for all production services.
|
|
95
|
+
2. Traffic shaping during rollout: network load balancer or service mesh gradually shifts traffic from the old version
|
|
96
|
+
to the new version. Hard cutover is prohibited.
|
|
97
|
+
3. APIs must be backward-compatible across a deployment window. Breaking API changes require a versioned endpoint
|
|
98
|
+
strategy before the old version is retired.
|
|
99
|
+
4. Schema migrations (database, event schema) are non-breaking and phased:
|
|
100
|
+
- Phase 1: add new column/field (backward-compatible with old code).
|
|
101
|
+
- Phase 2: deploy new code that writes both old and new.
|
|
102
|
+
- Phase 3: backfill and migrate data.
|
|
103
|
+
- Phase 4: remove old column/field only after old code is fully retired.
|
|
104
|
+
5. Feature flags or service mesh routing rules are used to gate new behavior during deployment. A feature can be
|
|
105
|
+
promoted or rolled back independently of the artifact version.
|
|
112
106
|
|
|
113
107
|
### Service Mesh
|
|
114
108
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
109
|
+
1. All east-west (pod-to-pod) traffic runs through the service mesh. Direct pod-to-pod communication bypassing the mesh
|
|
110
|
+
is prohibited in staging and production.
|
|
111
|
+
2. The mesh enforces mTLS, authorization policy, and traffic observability on all managed traffic.
|
|
112
|
+
3. Circuit breakers and retry budgets are configured per service. Default retry-all-failures behavior is prohibited;
|
|
113
|
+
retries must be limited and idempotent-safe.
|
|
120
114
|
|
|
121
115
|
### Secrets Management
|
|
122
116
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
security team.
|
|
117
|
+
1. Application secrets (database passwords, API keys, private keys) are injected at runtime from the approved secrets
|
|
118
|
+
manager. Secrets must not be embedded in container images, manifests, environment variable literals, or
|
|
119
|
+
version-controlled configuration.
|
|
120
|
+
2. Secrets are mounted as in-memory volumes or environment variables injected by the secrets sidecar/operator. Secrets
|
|
121
|
+
written to the container filesystem at rest are prohibited.
|
|
122
|
+
3. Secret access is logged by the secrets manager. Unexpected access patterns alert the security team.
|
|
130
123
|
|
|
131
124
|
## Policy and Compliance
|
|
132
125
|
|
|
133
126
|
### Change Management
|
|
134
127
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
43. CTO and ARB policy documents are archived and versioned. Historical policy versions are accessible.
|
|
128
|
+
1. All infrastructure changes are managed via GitOps or a declarative change management system. Out-of-band changes
|
|
129
|
+
(manual console, ad-hoc CLI) are prohibited in staging and production and will be detected and reverted by
|
|
130
|
+
reconciliation.
|
|
131
|
+
2. Production changes require approval from at least one person who is not the change author.
|
|
132
|
+
3. Every production change record includes a rollback plan. Changes without a tested rollback plan are not approved.
|
|
133
|
+
4. CTO and ARB policy documents are archived and versioned. Historical policy versions are accessible.
|
|
142
134
|
|
|
143
135
|
### Compliance
|
|
144
136
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
137
|
+
1. The platform maintains SOC-2 Type II compliance. Evidence collection is automated where possible.
|
|
138
|
+
2. GDPR and CCPA requirements apply to all data processing pipelines. Privacy impact assessments are required for new
|
|
139
|
+
data processing features that handle personal data.
|
|
140
|
+
3. A Secure Development Lifecycle (SDL) is followed: threat modeling, SAST, DAST, dependency scanning, and penetration
|
|
141
|
+
testing are performed on a defined cadence.
|
|
142
|
+
4. ISO 27001 and NIST SP 800-53 are used as optional benchmarks to inform control selection. Controls are documented but
|
|
143
|
+
full certification is optional unless contractually required.
|
|
152
144
|
|
|
153
145
|
## Do Not
|
|
154
146
|
|
package/governance/security.md
CHANGED
|
@@ -1,139 +1,131 @@
|
|
|
1
1
|
# Security Standards
|
|
2
2
|
|
|
3
|
-
These rules govern identity and access management, encryption, key management, and data handling.
|
|
4
|
-
|
|
3
|
+
These rules govern identity and access management, encryption, key management, and data handling. They are
|
|
4
|
+
non-negotiable unless explicitly superseded by a signed ADR.
|
|
5
5
|
|
|
6
|
-
**Maturity:** Required
|
|
7
|
-
**Version:** 1.0.0
|
|
8
|
-
**Last Reviewed:** 2026-03-09
|
|
6
|
+
**Maturity:** Required **Version:** 1.0.0 **Last Reviewed:** 2026-03-09
|
|
9
7
|
|
|
10
8
|
## Identity and Access Management
|
|
11
9
|
|
|
12
10
|
### Federated Authentication
|
|
13
11
|
|
|
14
|
-
1. All human-facing authentication uses a federated identity provider (IdP) via OIDC or SAML 2.0.
|
|
15
|
-
|
|
16
|
-
2. The approved AuthN vendor(s) are documented in the internal vendor registry. No additional identity
|
|
17
|
-
|
|
18
|
-
3. Multi-factor authentication (MFA) is required for all human accounts. Phishing-resistant MFA
|
|
19
|
-
|
|
12
|
+
1. All human-facing authentication uses a federated identity provider (IdP) via OIDC or SAML 2.0. Local
|
|
13
|
+
username/password stores are prohibited for production systems.
|
|
14
|
+
2. The approved AuthN vendor(s) are documented in the internal vendor registry. No additional identity providers are
|
|
15
|
+
introduced without ARB approval and a security review.
|
|
16
|
+
3. Multi-factor authentication (MFA) is required for all human accounts. Phishing-resistant MFA (FIDO2/WebAuthn) is
|
|
17
|
+
required for privileged and production access.
|
|
20
18
|
|
|
21
19
|
### Workload Identity
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
HS256-signed JWTs are prohibited in production.
|
|
21
|
+
1. Service-to-service authentication uses SPIFFE/SPIRE (or an equivalent SVID-based workload identity system). Static
|
|
22
|
+
shared secrets for service identity are prohibited.
|
|
23
|
+
2. SPIFFE Verifiable Identity Documents (SVIDs) are issued with a maximum 24-hour TTL and rotated automatically.
|
|
24
|
+
3. JWT-based identity is acceptable for external API integrations where SPIFFE is not available. JWTs must be signed
|
|
25
|
+
(RS256 or ES256 minimum) and have an explicit `exp` claim. Unsigned or HS256-signed JWTs are prohibited in
|
|
26
|
+
production.
|
|
30
27
|
|
|
31
28
|
### Token Lifecycle and Revocation
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
1. Access tokens have a maximum lifetime of 15 minutes. Refresh tokens have a maximum lifetime of 8 hours for human
|
|
31
|
+
sessions; service refresh tokens do not exist (workload identity handles renewal).
|
|
32
|
+
2. Token revocation is effective within 60 seconds. Caches that hold token validation results must honor the revocation
|
|
33
|
+
TTL.
|
|
34
|
+
3. Refresh tokens are single-use and rotated on every use. Reuse of a refresh token triggers immediate session
|
|
35
|
+
termination and a security alert.
|
|
36
|
+
4. All issued tokens are logged with: issuer, subject, audience, `jti`, issued-at, and expiry.
|
|
40
37
|
|
|
41
38
|
## Authorization
|
|
42
39
|
|
|
43
40
|
### Service-Level Routing AuthZ
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
gateway layer.
|
|
42
|
+
1. API gateways and ingress controllers enforce coarse-grained authorization (service-to-service trust boundaries)
|
|
43
|
+
before traffic reaches application pods.
|
|
44
|
+
2. Services must not trust the caller's claimed identity from request headers alone; the identity assertion must be
|
|
45
|
+
cryptographically verified (mTLS client cert or verified JWT) by the mesh or gateway layer.
|
|
50
46
|
|
|
51
47
|
### Role-Based Access Control (RBAC)
|
|
52
48
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
1. RBAC roles are defined at the minimum privilege required for each function. There are no "superuser" roles in
|
|
50
|
+
production except for documented break-glass accounts.
|
|
51
|
+
2. Role assignments are reviewed quarterly. Stale role assignments are revoked automatically after 90 days without
|
|
52
|
+
reaffirmation.
|
|
53
|
+
3. Role definitions and assignments are stored in version-controlled configuration. Manual UI-based role grants that
|
|
54
|
+
bypass version control are prohibited.
|
|
59
55
|
|
|
60
56
|
### Attribute-Based Access Control (ABAC)
|
|
61
57
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
1. Fine-grained access decisions (data-level, row-level) are implemented via ABAC policies in the centralized policy
|
|
59
|
+
engine (OPA or equivalent).
|
|
60
|
+
2. ABAC policies are co-located with the service that owns the resource. Cross-service policy definitions require ARB
|
|
61
|
+
approval.
|
|
66
62
|
|
|
67
63
|
### Centralized Policy Engine
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
decisions to fail closed (deny), not fail open (permit).
|
|
65
|
+
1. The approved policy engine (OPA or equivalent) is the single source of truth for all authorization decisions.
|
|
66
|
+
Services must not implement ad-hoc authorization logic that duplicates or overrides centralized policy.
|
|
67
|
+
2. Policies are version-controlled. Every policy change requires a review and an audit log entry.
|
|
68
|
+
3. The policy engine exposes a health endpoint; its unavailability must cause authorization decisions to fail closed
|
|
69
|
+
(deny), not fail open (permit).
|
|
75
70
|
|
|
76
71
|
### Policy Versioning and Rollback
|
|
77
72
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
engine's rollback mechanism.
|
|
73
|
+
1. Policies are tagged with a version identifier. The current version in force is queryable from the policy engine.
|
|
74
|
+
2. Any policy change can be rolled back to the previous version within 5 minutes via the policy engine's rollback
|
|
75
|
+
mechanism.
|
|
82
76
|
|
|
83
77
|
### Delegated Permissions
|
|
84
78
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
1. Delegated admin domains (e.g., team-level RBAC management) are scoped to the team's namespace. Cross-namespace
|
|
80
|
+
privilege delegation requires ARB approval.
|
|
81
|
+
2. OAuth 2.0 delegated scopes must be explicitly documented per API. Broad wildcard scopes (e.g., `*`, `admin`) are
|
|
82
|
+
prohibited unless the API is itself an admin API.
|
|
89
83
|
|
|
90
84
|
## Encryption
|
|
91
85
|
|
|
92
86
|
### Encryption in Transit
|
|
93
87
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
88
|
+
1. All traffic between pods, nodes, and external systems is encrypted. Plaintext communication inside the cluster is
|
|
89
|
+
prohibited in staging and production.
|
|
90
|
+
2. Service-to-service encryption is enforced via mTLS at the service mesh layer.
|
|
91
|
+
3. Traffic to external APIs uses TLS 1.2 minimum; TLS 1.3 preferred. See `governance/platform.md` for cipher suite
|
|
92
|
+
requirements.
|
|
99
93
|
|
|
100
94
|
### Encryption at Rest
|
|
101
95
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
96
|
+
1. All persistent data stores (databases, object storage, message queues, caches) encrypt data at rest using AES-256 or
|
|
97
|
+
equivalent.
|
|
98
|
+
2. Encryption keys for data at rest are managed by the approved key management service (KMS) and never stored alongside
|
|
99
|
+
the data they protect.
|
|
100
|
+
3. Backup and snapshot data is encrypted with the same or stronger controls as primary data.
|
|
107
101
|
|
|
108
102
|
### Key Management
|
|
109
103
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
1. The approved KMS vendor(s) are documented in the internal vendor registry. Application-managed key stores (manual key
|
|
105
|
+
files, hardcoded keys) are prohibited.
|
|
106
|
+
2. Encryption keys are rotated on a defined schedule: symmetric keys every 90 days, asymmetric keys every 12 months,
|
|
107
|
+
unless a shorter rotation is required by compliance or incident response.
|
|
108
|
+
3. Key rotation is zero-downtime. Services must reload keys without restart.
|
|
115
109
|
|
|
116
110
|
### Formal Rapid Key Rotation
|
|
117
111
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
37. Emergency key rotation is tested in staging at least quarterly. Results are documented.
|
|
112
|
+
1. The platform must support emergency key rotation with an SLA of 5 minutes or less for the entire network.
|
|
113
|
+
2. Services must reload encryption keys upon receiving a designated OS signal (e.g., SIGUSR1) or a KMS-pushed
|
|
114
|
+
notification, without process restart.
|
|
115
|
+
3. Key rotation events are logged in the audit log with: key ID, rotation trigger (scheduled or emergency), actor, and
|
|
116
|
+
timestamp.
|
|
117
|
+
4. Emergency key rotation is tested in staging at least quarterly. Results are documented.
|
|
125
118
|
|
|
126
119
|
## Data Classification and Handling
|
|
127
120
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
compliance change.
|
|
121
|
+
1. All data is classified at creation time as one of: `public`, `internal`, `confidential`, or `restricted`.
|
|
122
|
+
Classification is stored as metadata alongside the data.
|
|
123
|
+
2. `confidential` and `restricted` data must be encrypted at rest and in transit, accessed only via authorized roles,
|
|
124
|
+
and logged on every access.
|
|
125
|
+
3. `restricted` data (e.g., payment card data, health records) must also be isolated in dedicated storage with
|
|
126
|
+
network-level segmentation from general-purpose stores.
|
|
127
|
+
4. Data handling procedures for each classification level are documented in the internal data handling policy. That
|
|
128
|
+
policy is reviewed annually and after any significant breach or compliance change.
|
|
137
129
|
|
|
138
130
|
## Do Not
|
|
139
131
|
|
package/governance/testing.md
CHANGED
|
@@ -2,17 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
These rules govern all test code and test infrastructure in this project. They are non-negotiable.
|
|
4
4
|
|
|
5
|
-
**Maturity:** Required
|
|
6
|
-
**Version:** 1.0.0
|
|
7
|
-
**Last Reviewed:** 2026-03-14
|
|
5
|
+
**Maturity:** Required **Version:** 1.1.0 **Last Reviewed:** 2026-05-24
|
|
8
6
|
|
|
9
7
|
## Core Principle
|
|
10
8
|
|
|
11
9
|
Unit tests do not cross system boundaries.
|
|
12
10
|
|
|
13
|
-
A system boundary is anything that requires a network peer, an OS service, or an external process.
|
|
14
|
-
|
|
15
|
-
cluster-level suite — not in a `_test.go` file.
|
|
11
|
+
A system boundary is anything that requires a network peer, an OS service, or an external process. If a test needs one
|
|
12
|
+
of those, it is an integration test and belongs in BATS, Compose, or a cluster-level suite — not in a `_test.go` file.
|
|
16
13
|
|
|
17
14
|
## What Goes in Unit Tests
|
|
18
15
|
|
|
@@ -36,8 +33,8 @@ cluster-level suite — not in a `_test.go` file.
|
|
|
36
33
|
|
|
37
34
|
Do not mock external systems. Use real implementations in integration tests.
|
|
38
35
|
|
|
39
|
-
Mocks replicate the mock author's understanding of a contract at a point in time. When the real
|
|
40
|
-
|
|
36
|
+
Mocks replicate the mock author's understanding of a contract at a point in time. When the real system changes, mocks
|
|
37
|
+
silently pass. Real tools catch contract drift.
|
|
41
38
|
|
|
42
39
|
Acceptable alternatives to real systems:
|
|
43
40
|
|
|
@@ -49,12 +46,12 @@ Acceptable alternatives to real systems:
|
|
|
49
46
|
|
|
50
47
|
Every project MUST define the following test layers. Names and Makefile targets are fixed.
|
|
51
48
|
|
|
52
|
-
| Layer
|
|
53
|
-
|
|
54
|
-
| Unit
|
|
55
|
-
| Integration | `make integration-test` | Binary + real peers
|
|
56
|
-
| Compose
|
|
57
|
-
| Kubernetes
|
|
49
|
+
| Layer | Makefile target | Scope | External deps |
|
|
50
|
+
| ----------- | ----------------------- | -------------------------------------- | -------------------- |
|
|
51
|
+
| Unit | `make unit-test` | In-process logic; no system boundaries | None |
|
|
52
|
+
| Integration | `make integration-test` | Binary + real peers | Test daemons on PATH |
|
|
53
|
+
| Compose | `make test-compose` | Full stack via Docker Compose | Docker |
|
|
54
|
+
| Kubernetes | `make test-k8s` | Helm deploy + pod probes | kind / Docker |
|
|
58
55
|
|
|
59
56
|
## Test File Layout
|
|
60
57
|
|
|
@@ -70,15 +67,64 @@ Every project MUST define the following test layers. Names and Makefile targets
|
|
|
70
67
|
- Upload JUnit XML as a workflow artifact for test history and flake detection.
|
|
71
68
|
- Coverage profile MUST be produced on every unit test run.
|
|
72
69
|
- `make coverage` prints: total %, uncovered statement count, total statement count.
|
|
73
|
-
- `make ci-coverage-delta` compares PR head coverage against the merge-target base branch;
|
|
74
|
-
|
|
70
|
+
- `make ci-coverage-delta` compares PR head coverage against the merge-target base branch; fails if coverage drops
|
|
71
|
+
beyond the configured threshold.
|
|
72
|
+
|
|
73
|
+
## Coverage Regression Policy
|
|
74
|
+
|
|
75
|
+
**Per-file coverage SHALL NEVER decrease.** This is a non-negotiable, unwaivable invariant of every change. No
|
|
76
|
+
`STANDARDS_OVERRIDES.md` entry can permit a regression; there is nothing to override because the rule is procedural,
|
|
77
|
+
not policy.
|
|
78
|
+
|
|
79
|
+
Granularity, baseline, comparison:
|
|
80
|
+
|
|
81
|
+
- The unit of comparison is **per-file line coverage**: the ratio `LH / LF` for each `SF:` record in the LCOV report.
|
|
82
|
+
Totals or aggregate percentages are insufficient — a per-file improvement that masks a per-file regression is a
|
|
83
|
+
violation.
|
|
84
|
+
- The baseline lives at `tests/coverage-baseline.lcov` in the consumer repo, tracked in git. It is updated only as
|
|
85
|
+
part of a change that strictly increases (or holds) coverage on every file present in both the baseline and the
|
|
86
|
+
current report, AND that meets the new-file floor (below) for every file added in that change set.
|
|
87
|
+
- Comparison is `current vs baseline`:
|
|
88
|
+
- **Existing files** (`SF:` present in both): assert
|
|
89
|
+
`current.LH/current.LF >= baseline.LH/baseline.LF`. Equal or higher passes; lower fails.
|
|
90
|
+
- **New files** (`SF:` present only in current): assert
|
|
91
|
+
`current.LH/current.LF >= 0.95`. New files MUST land at ≥ 95% coverage. Files added with less than 95% per-file
|
|
92
|
+
coverage cause the gate to fail. This is an absolute floor — no override.
|
|
93
|
+
- **Deleted files** (`SF:` present only in baseline): drop out of comparison, but the baseline entry MUST be removed
|
|
94
|
+
in the same change set; otherwise the audit flags a stale baseline.
|
|
95
|
+
- The enforcement target is `make ci-coverage-no-regression`. The implementation lives at
|
|
96
|
+
`scripts/test/coverage-no-regression.sh` (canonical; shipped). It consumes the LCOV from `make coverage` and the
|
|
97
|
+
baseline at `tests/coverage-baseline.lcov`; exits non-zero on any per-file regression OR new-file floor violation.
|
|
98
|
+
|
|
99
|
+
Two consequences when a regression is detected:
|
|
100
|
+
|
|
101
|
+
1. **CI gates the merge.** `make ci-coverage-no-regression` exits non-zero. The PR is rejected.
|
|
102
|
+
2. **Assistant workflow procedure.** An assistant detecting a regression in its own work-in-progress MUST NOT present
|
|
103
|
+
the change for human approval. It MUST revert the offending change set, then report to the human: the file(s) whose
|
|
104
|
+
coverage decreased, the prior and current percentages, and the revert. The decision about next action belongs to
|
|
105
|
+
the human; the decision about whether to present is procedural and not the assistant's to make.
|
|
106
|
+
|
|
107
|
+
Edge cases:
|
|
108
|
+
|
|
109
|
+
- **Removing a file entirely is allowed.** When the file is removed, its baseline entry is removed in the same change
|
|
110
|
+
set. The comparison sees no `SF:` for that path in either side.
|
|
111
|
+
- **Splitting a file** (one file becomes two) is treated as removal + two new files. Each resulting file is subject
|
|
112
|
+
to the new-file 95% floor from its first measurement; the original baseline entry is removed in the same change set.
|
|
113
|
+
- **Baseline initialization** (the first run of `make coverage-baseline-init` against a repo with no prior baseline)
|
|
114
|
+
is exempt from the 95% new-file floor — every file is captured at its current ratio to seed the baseline. From the
|
|
115
|
+
second change set onward the rule binds in full: existing-file no-regression PLUS new-file 95% floor.
|
|
116
|
+
- **Non-determinism in coverage tooling** (per-file numbers that drift across runs without code change) is itself a
|
|
117
|
+
violation. The cause must be fixed before the baseline can be trusted.
|
|
118
|
+
|
|
119
|
+
This applies to every language with a per-file coverage report: Go (`go test -coverprofile`), Rust (`cargo-llvm-cov`
|
|
120
|
+
LCOV), and any other.
|
|
75
121
|
|
|
76
122
|
## Test Modification Policy
|
|
77
123
|
|
|
78
124
|
Test files are protected. Do not modify test files without explicit prior authorization.
|
|
79
125
|
|
|
80
|
-
When a test fails, the correct response is to find and fix the root cause in production code —
|
|
81
|
-
|
|
126
|
+
When a test fails, the correct response is to find and fix the root cause in production code — not to adjust the test to
|
|
127
|
+
pass. A failing test is a signal, not an obstacle.
|
|
82
128
|
|
|
83
129
|
Exceptions require explicit approval:
|
|
84
130
|
|
|
@@ -88,8 +134,8 @@ Exceptions require explicit approval:
|
|
|
88
134
|
|
|
89
135
|
## FIPS Compatibility
|
|
90
136
|
|
|
91
|
-
Tests that use `InsecureSkipVerify`, self-signed certs via `httptest`, or non-FIPS algorithms
|
|
92
|
-
|
|
137
|
+
Tests that use `InsecureSkipVerify`, self-signed certs via `httptest`, or non-FIPS algorithms MUST be guarded with a
|
|
138
|
+
FIPS skip:
|
|
93
139
|
|
|
94
140
|
```go
|
|
95
141
|
if os.Getenv("GOFIPS140") != "" {
|