azcodr 1.5.0 → 1.5.1
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/.agents/hooks.json +42 -0
- package/.agents/hooks.json.example +42 -42
- package/.agents/mcp_config.json.example +6 -1
- package/.agents/scripts/safety_guard.sh +34 -16
- package/.agents/scripts/verify_completion.sh +27 -13
- package/.agents/skills/agentic-architect/SKILL.md +125 -125
- package/.agents/skills/agentic-architect/references/agents_md_template.md +62 -62
- package/.agents/skills/agentic-architect/references/refinement_workflow.md +32 -32
- package/.agents/skills/agentic-architect/references/skill_architecture_inquiry.md +63 -63
- package/.agents/skills/agentic-architect/references/skill_template.md +56 -56
- package/.agents/skills/agentic-architect/scripts/validate_agentic_configs.sh +401 -362
- package/.agents/skills/clean-code-refactor/SKILL.md +91 -91
- package/.agents/skills/clean-code-refactor/references/clean_code_smells.md +27 -27
- package/.agents/skills/clean-code-refactor/references/design_patterns_ts.md +65 -65
- package/.agents/skills/compliance-audit/SKILL.md +120 -120
- package/.agents/skills/compliance-audit/references/owasp_top10_controls.md +16 -16
- package/.agents/skills/compliance-audit/references/soc2_iso_controls.md +28 -28
- package/.agents/skills/lets-build/SKILL.md +173 -172
- package/.agents/skills/lets-build/references/architecture_interview_matrix.md +115 -115
- package/.agents/skills/lets-build/references/hexagonal_bootstrap_scaffolds.md +160 -160
- package/.agents/skills/lets-build/references/project_readme_template.md +79 -79
- package/.agents/skills/lets-build/scripts/bootstrap_workspace.sh +255 -253
- package/.agents/skills/product-analyst/SKILL.md +154 -154
- package/.agents/skills/product-analyst/references/backlog_ordering_techniques.md +107 -107
- package/.agents/skills/product-analyst/references/gherkin_patterns.md +46 -46
- package/.agents/skills/product-analyst/references/invest_checklist.md +38 -38
- package/.agents/skills/product-analyst/references/okr_alignment_guide.md +76 -76
- package/.agents/skills/product-analyst/references/smart_tasks.md +59 -59
- package/.agents/skills/relentless-questioner/SKILL.md +128 -128
- package/.agents/skills/relentless-questioner/references/adaptive_question_trees.md +102 -102
- package/.editorconfig +19 -19
- package/.github/copilot-instructions.md +1 -0
- package/.github/workflows/ci.yml +56 -0
- package/.gitignore +25 -25
- package/AGENTS.md +102 -102
- package/LICENSE +21 -21
- package/README.md +154 -154
- package/bin/azcodr.js +228 -228
- package/data/.gitkeep +0 -0
- package/docs/knowledge/ubiquitous_language.md +18 -18
- package/docs/rules/agentic_configuration.md +259 -259
- package/docs/rules/api_architecture.md +179 -179
- package/docs/rules/authentication.md +76 -76
- package/docs/rules/authorization.md +75 -75
- package/docs/rules/caching.md +69 -69
- package/docs/rules/clean_code.md +62 -62
- package/docs/rules/cloud_native.md +41 -41
- package/docs/rules/cqrs.md +203 -203
- package/docs/rules/database_design.md +125 -125
- package/docs/rules/database_operations.md +69 -69
- package/docs/rules/design_patterns.md +98 -98
- package/docs/rules/devops_ci_cd.md +76 -76
- package/docs/rules/domain_driven_design.md +122 -122
- package/docs/rules/error_handling.md +52 -52
- package/docs/rules/feature_flags.md +59 -59
- package/docs/rules/frontend_architecture.md +157 -157
- package/docs/rules/multitenancy_architecture.md +98 -98
- package/docs/rules/product_ownership.md +127 -127
- package/docs/rules/project_management.md +49 -49
- package/docs/rules/relentless_questioning.md +52 -52
- package/docs/rules/requirements_engineering.md +98 -98
- package/docs/rules/security_compliance.md +53 -53
- package/docs/rules/server_driven_ui.md +88 -88
- package/docs/rules/test_driven_development.md +185 -185
- package/docs/rules/transactional_email.md +27 -27
- package/docs/rules/type_safety.md +65 -65
- package/docs/rules/ui_ux_architecture.md +150 -150
- package/docs/rules/workflow_state_machines.md +117 -117
- package/lib/index.d.ts +134 -123
- package/lib/index.js +5 -5
- package/lib/scaffold.js +399 -351
- package/memory.md +36 -36
- package/package.json +62 -59
- package/scripts/test_coverage.js +38 -0
- package/scripts/validate.js +246 -0
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
# Enterprise Authorization, Policy-as-Code & ReBAC
|
|
2
|
-
|
|
3
|
-
> **Core Mandate:** Enforce granular Role-Based, Attribute-Based, and Relationship-Based Access Control (RBAC/ABAC/ReBAC) via Open Policy Agent (OPA), OpenFGA, or Cerbos across all API boundaries.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Declarative Policy-as-Code with Open Policy Agent (OPA)
|
|
8
|
-
|
|
9
|
-
Standardize on **Open Policy Agent (OPA)** and the **Rego** language for externalized, auditable policy evaluation:
|
|
10
|
-
|
|
11
|
-
```rego
|
|
12
|
-
package app.authz
|
|
13
|
-
|
|
14
|
-
default allow = false
|
|
15
|
-
|
|
16
|
-
# Allow tenant admin to manage all resources within their tenant
|
|
17
|
-
allow if {
|
|
18
|
-
input.user.role == "ADMIN"
|
|
19
|
-
input.user.tenant_id == input.resource.tenant_id
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
# Allow standard member to update drafts in their tenant
|
|
23
|
-
allow if {
|
|
24
|
-
input.action == "update"
|
|
25
|
-
input.resource.type == "Order"
|
|
26
|
-
input.resource.status == "DRAFT"
|
|
27
|
-
input.user.tenant_id == input.resource.tenant_id
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### High-Performance In-Process Evaluation (OPA WebAssembly)
|
|
32
|
-
- In addition to running OPA as a local daemon or sidecar over HTTP/gRPC, compile Rego policies to **`.wasm`** binaries.
|
|
33
|
-
- Embedded OPA Wasm modules evaluate policies directly within application process memory across any language (Rust, Go, Python, Java, Node) with sub-millisecond latency and zero network roundtrips.
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## 2. Relationship-Based Access Control (ReBAC): OpenFGA / Zanzibar
|
|
38
|
-
|
|
39
|
-
For multi-tenant organizational hierarchies, shared folders, and delegated permissions, standardize on **OpenFGA** (CNCF):
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
type user
|
|
43
|
-
type organization
|
|
44
|
-
relations
|
|
45
|
-
define admin: [user]
|
|
46
|
-
define member: [user]
|
|
47
|
-
|
|
48
|
-
type document
|
|
49
|
-
relations
|
|
50
|
-
define owner: [user]
|
|
51
|
-
define editor: [user] or owner
|
|
52
|
-
define viewer: [user] or editor or member from parent_org
|
|
53
|
-
define parent_org: [organization]
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Evaluated via standard gRPC/REST clients from any polyglot service:
|
|
57
|
-
`check(user="user:alice", relation="editor", object="document:doc-100")`
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## 3. Server-Side Policy Enforcement Point (PEP) Guarding
|
|
62
|
-
|
|
63
|
-
- **Mandatory Enforcement**: Never rely on client-side permission checks. Every backend endpoint or command handler must verify authorization at the boundary before executing domain logic:
|
|
64
|
-
```
|
|
65
|
-
decision = PolicyEngine.evaluate({
|
|
66
|
-
principal: currentUser,
|
|
67
|
-
action: "Order.Update",
|
|
68
|
-
resource: targetOrder,
|
|
69
|
-
context: { ip: request.ip, time: now() }
|
|
70
|
-
})
|
|
71
|
-
if (!decision.allowed) {
|
|
72
|
-
return Forbidden("INSUFFICIENT_PERMISSIONS")
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
- **Immutable System Role Invariants**: System-level roles (e.g. `OWNER`, `SECURITY_ADMIN`) must be protected by explicit policy rules preventing self-demotion or unauthorized role grants.
|
|
1
|
+
# Enterprise Authorization, Policy-as-Code & ReBAC
|
|
2
|
+
|
|
3
|
+
> **Core Mandate:** Enforce granular Role-Based, Attribute-Based, and Relationship-Based Access Control (RBAC/ABAC/ReBAC) via Open Policy Agent (OPA), OpenFGA, or Cerbos across all API boundaries.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Declarative Policy-as-Code with Open Policy Agent (OPA)
|
|
8
|
+
|
|
9
|
+
Standardize on **Open Policy Agent (OPA)** and the **Rego** language for externalized, auditable policy evaluation:
|
|
10
|
+
|
|
11
|
+
```rego
|
|
12
|
+
package app.authz
|
|
13
|
+
|
|
14
|
+
default allow = false
|
|
15
|
+
|
|
16
|
+
# Allow tenant admin to manage all resources within their tenant
|
|
17
|
+
allow if {
|
|
18
|
+
input.user.role == "ADMIN"
|
|
19
|
+
input.user.tenant_id == input.resource.tenant_id
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# Allow standard member to update drafts in their tenant
|
|
23
|
+
allow if {
|
|
24
|
+
input.action == "update"
|
|
25
|
+
input.resource.type == "Order"
|
|
26
|
+
input.resource.status == "DRAFT"
|
|
27
|
+
input.user.tenant_id == input.resource.tenant_id
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### High-Performance In-Process Evaluation (OPA WebAssembly)
|
|
32
|
+
- In addition to running OPA as a local daemon or sidecar over HTTP/gRPC, compile Rego policies to **`.wasm`** binaries.
|
|
33
|
+
- Embedded OPA Wasm modules evaluate policies directly within application process memory across any language (Rust, Go, Python, Java, Node) with sub-millisecond latency and zero network roundtrips.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Relationship-Based Access Control (ReBAC): OpenFGA / Zanzibar
|
|
38
|
+
|
|
39
|
+
For multi-tenant organizational hierarchies, shared folders, and delegated permissions, standardize on **OpenFGA** (CNCF):
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
type user
|
|
43
|
+
type organization
|
|
44
|
+
relations
|
|
45
|
+
define admin: [user]
|
|
46
|
+
define member: [user]
|
|
47
|
+
|
|
48
|
+
type document
|
|
49
|
+
relations
|
|
50
|
+
define owner: [user]
|
|
51
|
+
define editor: [user] or owner
|
|
52
|
+
define viewer: [user] or editor or member from parent_org
|
|
53
|
+
define parent_org: [organization]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Evaluated via standard gRPC/REST clients from any polyglot service:
|
|
57
|
+
`check(user="user:alice", relation="editor", object="document:doc-100")`
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 3. Server-Side Policy Enforcement Point (PEP) Guarding
|
|
62
|
+
|
|
63
|
+
- **Mandatory Enforcement**: Never rely on client-side permission checks. Every backend endpoint or command handler must verify authorization at the boundary before executing domain logic:
|
|
64
|
+
```
|
|
65
|
+
decision = PolicyEngine.evaluate({
|
|
66
|
+
principal: currentUser,
|
|
67
|
+
action: "Order.Update",
|
|
68
|
+
resource: targetOrder,
|
|
69
|
+
context: { ip: request.ip, time: now() }
|
|
70
|
+
})
|
|
71
|
+
if (!decision.allowed) {
|
|
72
|
+
return Forbidden("INSUFFICIENT_PERMISSIONS")
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
- **Immutable System Role Invariants**: System-level roles (e.g. `OWNER`, `SECURITY_ADMIN`) must be protected by explicit policy rules preventing self-demotion or unauthorized role grants.
|
package/docs/rules/caching.md
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
# Caching Strategies & Event-Driven Invalidation
|
|
2
|
-
|
|
3
|
-
> **Core Mandate:** Enforce Cache Port semantics with namespaced keys, jittered TTLs, XFetch stampede defense, event-driven cache invalidation, and HTTP conditional caching (ETags / 304).
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. The YAGNI Gate: Database First, Caching Second
|
|
8
|
-
|
|
9
|
-
Caching introduces state duplication, cache invalidation race conditions, and memory overhead. **Caching is never a substitute for missing database indexes or poorly structured SQL queries.**
|
|
10
|
-
|
|
11
|
-
```mermaid
|
|
12
|
-
flowchart TD
|
|
13
|
-
subgraph CachingGate["Caching YAGNI Gate"]
|
|
14
|
-
B1["1. Simple Baseline (Day 1)<br/>• Relational queries with composite indexes<br/>• Request-scoped in-memory DataLoader batching to eliminate N+1<br/>• Zero distributed cache infrastructure (no Redis / Memcached)"]
|
|
15
|
-
B2["2. Anti-Triggers (Forbidden)<br/>• Queries that are slow due to missing indexes or sequential scans<br/>• High-write / high-churn entities (write-heavy mutation streams)<br/>• Low-traffic administrative or internal operational queries"]
|
|
16
|
-
B3["3. The Tipping Point (Graduation)<br/>• Query has been optimized with EXPLAIN ANALYZE, but p99 latency still exceeds SLA (> 100ms)<br/>• Read-to-write asymmetry on the entity exceeds 20:1<br/>• Downstream external API rate limits or third-party egress costs demand response caching"]
|
|
17
|
-
B1 -->|Forbidden if missing indexes| B2
|
|
18
|
-
B1 -->|Triggered by high read/write ratio| B3
|
|
19
|
-
end
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## 2. Abstract Cache Port & Cache-Aside Pattern
|
|
25
|
-
|
|
26
|
-
Application services interact with caching infrastructure through a swappable **Cache Port**, supporting any backend (Redis, Valkey, Dragonfly, KeyDB, Memcached, or in-memory LRU):
|
|
27
|
-
|
|
28
|
-
```mermaid
|
|
29
|
-
classDiagram
|
|
30
|
-
class CachePort {
|
|
31
|
-
<<interface>>
|
|
32
|
-
+get(key: string) Optional~string~
|
|
33
|
-
+set(key: string, value: string, ttlSeconds: number) void
|
|
34
|
-
+delete(key: string) void
|
|
35
|
-
+deletePattern(pattern: string) void
|
|
36
|
-
+acquireLock(lockKey: string, ttlMs: number) boolean
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### Cache-Aside Implementation & Stampede Defense
|
|
41
|
-
```
|
|
42
|
-
function getCachedOrFetch(cachePort, key, ttlSeconds, fetcher):
|
|
43
|
-
cachedValue = cachePort.get(key)
|
|
44
|
-
if cachedValue is present:
|
|
45
|
-
return deserialize(cachedValue)
|
|
46
|
-
|
|
47
|
-
freshValue = fetcher()
|
|
48
|
-
// Add 10% random jitter to TTL to prevent simultaneous expiration spikes
|
|
49
|
-
jitter = randomInt(0, floor(ttlSeconds * 0.1))
|
|
50
|
-
cachePort.set(key, serialize(freshValue), ttlSeconds + jitter)
|
|
51
|
-
return freshValue
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
For high-throughput cache regeneration, employ the **XFetch algorithm** (probabilistic early expiration) to asynchronously warm the cache before hard expiry.
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## 3. Key Namespacing & Event-Driven Invalidation
|
|
59
|
-
|
|
60
|
-
- **Universal Key Hierarchy**: Structure all keys hierarchically:
|
|
61
|
-
`tenant:{tenantId}:{entity}:{entityId}` (e.g. `tenant:123:order:987`)
|
|
62
|
-
- **Event-Driven Invalidation**: Invalidate affected cache keys immediately upon emitting domain mutation events (`OrderUpdated`, `CustomerDeleted`) rather than waiting for passive TTL expiry.
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## 4. HTTP Conditional Caching (ETags)
|
|
67
|
-
|
|
68
|
-
- Generate strong cryptographic `ETag` hashes (e.g. SHA-256 of representation or resource version) for cacheable `GET` endpoints.
|
|
69
|
-
- Return **`304 Not Modified`** with zero payload body when inbound requests present matching `If-None-Match` headers, preserving bandwidth and client CPU.
|
|
1
|
+
# Caching Strategies & Event-Driven Invalidation
|
|
2
|
+
|
|
3
|
+
> **Core Mandate:** Enforce Cache Port semantics with namespaced keys, jittered TTLs, XFetch stampede defense, event-driven cache invalidation, and HTTP conditional caching (ETags / 304).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. The YAGNI Gate: Database First, Caching Second
|
|
8
|
+
|
|
9
|
+
Caching introduces state duplication, cache invalidation race conditions, and memory overhead. **Caching is never a substitute for missing database indexes or poorly structured SQL queries.**
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart TD
|
|
13
|
+
subgraph CachingGate["Caching YAGNI Gate"]
|
|
14
|
+
B1["1. Simple Baseline (Day 1)<br/>• Relational queries with composite indexes<br/>• Request-scoped in-memory DataLoader batching to eliminate N+1<br/>• Zero distributed cache infrastructure (no Redis / Memcached)"]
|
|
15
|
+
B2["2. Anti-Triggers (Forbidden)<br/>• Queries that are slow due to missing indexes or sequential scans<br/>• High-write / high-churn entities (write-heavy mutation streams)<br/>• Low-traffic administrative or internal operational queries"]
|
|
16
|
+
B3["3. The Tipping Point (Graduation)<br/>• Query has been optimized with EXPLAIN ANALYZE, but p99 latency still exceeds SLA (> 100ms)<br/>• Read-to-write asymmetry on the entity exceeds 20:1<br/>• Downstream external API rate limits or third-party egress costs demand response caching"]
|
|
17
|
+
B1 -->|Forbidden if missing indexes| B2
|
|
18
|
+
B1 -->|Triggered by high read/write ratio| B3
|
|
19
|
+
end
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. Abstract Cache Port & Cache-Aside Pattern
|
|
25
|
+
|
|
26
|
+
Application services interact with caching infrastructure through a swappable **Cache Port**, supporting any backend (Redis, Valkey, Dragonfly, KeyDB, Memcached, or in-memory LRU):
|
|
27
|
+
|
|
28
|
+
```mermaid
|
|
29
|
+
classDiagram
|
|
30
|
+
class CachePort {
|
|
31
|
+
<<interface>>
|
|
32
|
+
+get(key: string) Optional~string~
|
|
33
|
+
+set(key: string, value: string, ttlSeconds: number) void
|
|
34
|
+
+delete(key: string) void
|
|
35
|
+
+deletePattern(pattern: string) void
|
|
36
|
+
+acquireLock(lockKey: string, ttlMs: number) boolean
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Cache-Aside Implementation & Stampede Defense
|
|
41
|
+
```
|
|
42
|
+
function getCachedOrFetch(cachePort, key, ttlSeconds, fetcher):
|
|
43
|
+
cachedValue = cachePort.get(key)
|
|
44
|
+
if cachedValue is present:
|
|
45
|
+
return deserialize(cachedValue)
|
|
46
|
+
|
|
47
|
+
freshValue = fetcher()
|
|
48
|
+
// Add 10% random jitter to TTL to prevent simultaneous expiration spikes
|
|
49
|
+
jitter = randomInt(0, floor(ttlSeconds * 0.1))
|
|
50
|
+
cachePort.set(key, serialize(freshValue), ttlSeconds + jitter)
|
|
51
|
+
return freshValue
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For high-throughput cache regeneration, employ the **XFetch algorithm** (probabilistic early expiration) to asynchronously warm the cache before hard expiry.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 3. Key Namespacing & Event-Driven Invalidation
|
|
59
|
+
|
|
60
|
+
- **Universal Key Hierarchy**: Structure all keys hierarchically:
|
|
61
|
+
`tenant:{tenantId}:{entity}:{entityId}` (e.g. `tenant:123:order:987`)
|
|
62
|
+
- **Event-Driven Invalidation**: Invalidate affected cache keys immediately upon emitting domain mutation events (`OrderUpdated`, `CustomerDeleted`) rather than waiting for passive TTL expiry.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 4. HTTP Conditional Caching (ETags)
|
|
67
|
+
|
|
68
|
+
- Generate strong cryptographic `ETag` hashes (e.g. SHA-256 of representation or resource version) for cacheable `GET` endpoints.
|
|
69
|
+
- Return **`304 Not Modified`** with zero payload body when inbound requests present matching `If-None-Match` headers, preserving bandwidth and client CPU.
|
package/docs/rules/clean_code.md
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
# Clean Code & Pragmatic Programming Directives
|
|
2
|
-
|
|
3
|
-
> **Core Mandate:** Enforce intention-revealing naming, small focused functions, Command-Query Separation (CQS), Single Level of Abstraction (SLAP), and DRY pragmatic architecture across all codebases.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Clean Code Standards (Robert C. Martin)
|
|
8
|
-
|
|
9
|
-
- **Intention-Revealing Naming**: Names of variables, functions, and classes must describe why they exist, what they do, and how they are used. Avoid abbreviations, single-letter variables, and type-encoding prefixes.
|
|
10
|
-
- **Function Guidelines**:
|
|
11
|
-
- **Small and Focused**: Functions should do one thing, do it well, and do only that (Single Responsibility Principle). Max 20–30 lines per function.
|
|
12
|
-
- **Single Level of Abstraction (SLAP)**: Statements within a function must belong to the exact same level of abstraction.
|
|
13
|
-
- **Command-Query Separation (CQS)**: A function must either perform an action (mutate state) or return a value (query state), never both.
|
|
14
|
-
- **Argument Limit**: Limit function arguments to 3 or fewer. Bundle additional parameters into typed configuration DTOs or Value Objects.
|
|
15
|
-
- **Eliminate Side-Effects**: Functions must not have unexpected side effects (e.g. modifying passed arguments in-place or mutating global state) without explicit naming.
|
|
16
|
-
- **Dead Code**: Never leave commented-out code; rely entirely on version control history.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## 2. The Pragmatic Programmer Directives (Hunt & Thomas)
|
|
21
|
-
|
|
22
|
-
- **DRY (Don't Repeat Yourself)**: Every piece of knowledge must have a single, unambiguous, authoritative representation within the system. DRY applies to business domain knowledge, not superficial syntax duplication.
|
|
23
|
-
- **Orthogonality**: Eliminate coupling between unrelated modules. Changing one component must not cascade unexpected side effects into another.
|
|
24
|
-
- **Broken Windows Theory**: Never leave bad code, failing lint checks, or out-of-date documentation unfixed. Fix defects immediately before entropy normalizes.
|
|
25
|
-
- **Design by Contract (DbC)**: Define explicit preconditions (runtime boundary validation), postconditions (guaranteed response envelopes), and domain invariants.
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## 3. Evolutionary Architecture & Architectural Tipping Points (Ford, Parsons & Fowler)
|
|
30
|
-
|
|
31
|
-
Architecture is not a static Day 1 monument; it evolves incrementally as complexity grows. AI coding tools naturally take the path of least resistance (local token minimization), repeatedly appending code to simple files until they rot into a Big Ball of Mud. To eliminate **AI-Accelerated Architectural Drift**, the agent must pause and execute an architectural upgrade whenever code hits a **Deterministic Tipping Point**:
|
|
32
|
-
|
|
33
|
-
| Simple Baseline (Day 1) | Tipping Point / Mutation Trigger | Required Architectural Upgrade |
|
|
34
|
-
|---|---|---|
|
|
35
|
-
| **Flat Script / Single File** | File exceeds **250 lines**, or coordinates **>2 distinct I/O resources**, or is imported by **>3 distinct callers**. | **Extract Modular Subsystems:** Decouple domain logic from platform I/O; split into dedicated, focused submodules. |
|
|
36
|
-
| **Inline `if/else` or `switch` Cascades** | **Rule of Three:** The 3rd branching variant, payment provider, or protocol format is introduced. | **Strategy Pattern / Registry:** Replace conditional branching with a polymorphic Strategy interface or handler registry; update `memory.md`. |
|
|
37
|
-
| **In-Memory Store / Global State** | State requires **concurrent mutations**, **persistence across process restarts**, or **transactional rollback**. | **Repository Pattern & Persistence Port:** Introduce an explicit storage port contract; swap in-memory mock for a persistent database adapter. |
|
|
38
|
-
| **Direct Platform / Third-Party Calls** | External SDK or platform API is called from **>2 places**, or SDK throws untyped exceptions across boundaries. | **Adapter Pattern (Anti-Corruption Layer):** Wrap external SDK inside an application-owned port interface; mock only the owned interface in tests. |
|
|
39
|
-
| **Monolithic Domain Model** | The same business noun represents divergent lifecycles or definitions across workflows (e.g. `User` in Auth vs `User` in Billing). | **Bounded Context Split:** Separate into isolated domain contexts with explicit DTO / Anti-Corruption translation between them. |
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## 4. The "Refactor-Before-Add" Protocol (Kent Beck's Rule)
|
|
44
|
-
|
|
45
|
-
> *"Make the change easy (warning: this may be hard), then make the easy change."* — Kent Beck
|
|
46
|
-
|
|
47
|
-
Before writing production code for any new feature or user story, the agent must execute the **Refactor-Before-Add Check**:
|
|
48
|
-
1. **Assess Tipping Points**: Will adding this requirement cause any module, function, or data structure to cross an architectural tipping point?
|
|
49
|
-
2. **Phase A — Structural Refactoring (Under Green)**: If yes, refactor the existing architecture *first* while existing test suites remain 100% green. Zero behavioral changes; purely structural evolution.
|
|
50
|
-
3. **Phase B — ADR Mutation**: When an architectural tipping point is crossed, log a Lightweight Architectural Decision Record in `memory.md` summarizing the new structural boundary and trade-off.
|
|
51
|
-
4. **Phase C — Feature Implementation (Inner TDD)**: Only once the architecture cleanly accommodates the new capability, write the failing micro-test and implement the feature.
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## 5. Architectural Fitness Functions (Automated Tripwires)
|
|
56
|
-
|
|
57
|
-
Prevent AI-generated code rot using automated fitness functions integrated into linting and continuous verification:
|
|
58
|
-
- **File Length Gates**: Maximum 250–300 lines per file (ESLint `max-lines`).
|
|
59
|
-
- **Function Length Gates**: Maximum 20–30 lines per function (ESLint `max-lines-per-function`).
|
|
60
|
-
- **Dependency Direction Gates**: Enforce unidirectional import rules (e.g. `import/no-restricted-paths`, `dependency-cruiser`, `ArchUnit`) ensuring domain core never imports infrastructure or transport adapters.
|
|
61
|
-
- **Complexity Budgets**: Enforce cyclomatic complexity limits (maximum 10 per function).
|
|
62
|
-
If an AI attempt to add code violates any fitness function, the build fails immediately, blocking completion until the architecture is refactored.
|
|
1
|
+
# Clean Code & Pragmatic Programming Directives
|
|
2
|
+
|
|
3
|
+
> **Core Mandate:** Enforce intention-revealing naming, small focused functions, Command-Query Separation (CQS), Single Level of Abstraction (SLAP), and DRY pragmatic architecture across all codebases.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Clean Code Standards (Robert C. Martin)
|
|
8
|
+
|
|
9
|
+
- **Intention-Revealing Naming**: Names of variables, functions, and classes must describe why they exist, what they do, and how they are used. Avoid abbreviations, single-letter variables, and type-encoding prefixes.
|
|
10
|
+
- **Function Guidelines**:
|
|
11
|
+
- **Small and Focused**: Functions should do one thing, do it well, and do only that (Single Responsibility Principle). Max 20–30 lines per function.
|
|
12
|
+
- **Single Level of Abstraction (SLAP)**: Statements within a function must belong to the exact same level of abstraction.
|
|
13
|
+
- **Command-Query Separation (CQS)**: A function must either perform an action (mutate state) or return a value (query state), never both.
|
|
14
|
+
- **Argument Limit**: Limit function arguments to 3 or fewer. Bundle additional parameters into typed configuration DTOs or Value Objects.
|
|
15
|
+
- **Eliminate Side-Effects**: Functions must not have unexpected side effects (e.g. modifying passed arguments in-place or mutating global state) without explicit naming.
|
|
16
|
+
- **Dead Code**: Never leave commented-out code; rely entirely on version control history.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 2. The Pragmatic Programmer Directives (Hunt & Thomas)
|
|
21
|
+
|
|
22
|
+
- **DRY (Don't Repeat Yourself)**: Every piece of knowledge must have a single, unambiguous, authoritative representation within the system. DRY applies to business domain knowledge, not superficial syntax duplication.
|
|
23
|
+
- **Orthogonality**: Eliminate coupling between unrelated modules. Changing one component must not cascade unexpected side effects into another.
|
|
24
|
+
- **Broken Windows Theory**: Never leave bad code, failing lint checks, or out-of-date documentation unfixed. Fix defects immediately before entropy normalizes.
|
|
25
|
+
- **Design by Contract (DbC)**: Define explicit preconditions (runtime boundary validation), postconditions (guaranteed response envelopes), and domain invariants.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 3. Evolutionary Architecture & Architectural Tipping Points (Ford, Parsons & Fowler)
|
|
30
|
+
|
|
31
|
+
Architecture is not a static Day 1 monument; it evolves incrementally as complexity grows. AI coding tools naturally take the path of least resistance (local token minimization), repeatedly appending code to simple files until they rot into a Big Ball of Mud. To eliminate **AI-Accelerated Architectural Drift**, the agent must pause and execute an architectural upgrade whenever code hits a **Deterministic Tipping Point**:
|
|
32
|
+
|
|
33
|
+
| Simple Baseline (Day 1) | Tipping Point / Mutation Trigger | Required Architectural Upgrade |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| **Flat Script / Single File** | File exceeds **250 lines**, or coordinates **>2 distinct I/O resources**, or is imported by **>3 distinct callers**. | **Extract Modular Subsystems:** Decouple domain logic from platform I/O; split into dedicated, focused submodules. |
|
|
36
|
+
| **Inline `if/else` or `switch` Cascades** | **Rule of Three:** The 3rd branching variant, payment provider, or protocol format is introduced. | **Strategy Pattern / Registry:** Replace conditional branching with a polymorphic Strategy interface or handler registry; update `memory.md`. |
|
|
37
|
+
| **In-Memory Store / Global State** | State requires **concurrent mutations**, **persistence across process restarts**, or **transactional rollback**. | **Repository Pattern & Persistence Port:** Introduce an explicit storage port contract; swap in-memory mock for a persistent database adapter. |
|
|
38
|
+
| **Direct Platform / Third-Party Calls** | External SDK or platform API is called from **>2 places**, or SDK throws untyped exceptions across boundaries. | **Adapter Pattern (Anti-Corruption Layer):** Wrap external SDK inside an application-owned port interface; mock only the owned interface in tests. |
|
|
39
|
+
| **Monolithic Domain Model** | The same business noun represents divergent lifecycles or definitions across workflows (e.g. `User` in Auth vs `User` in Billing). | **Bounded Context Split:** Separate into isolated domain contexts with explicit DTO / Anti-Corruption translation between them. |
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 4. The "Refactor-Before-Add" Protocol (Kent Beck's Rule)
|
|
44
|
+
|
|
45
|
+
> *"Make the change easy (warning: this may be hard), then make the easy change."* — Kent Beck
|
|
46
|
+
|
|
47
|
+
Before writing production code for any new feature or user story, the agent must execute the **Refactor-Before-Add Check**:
|
|
48
|
+
1. **Assess Tipping Points**: Will adding this requirement cause any module, function, or data structure to cross an architectural tipping point?
|
|
49
|
+
2. **Phase A — Structural Refactoring (Under Green)**: If yes, refactor the existing architecture *first* while existing test suites remain 100% green. Zero behavioral changes; purely structural evolution.
|
|
50
|
+
3. **Phase B — ADR Mutation**: When an architectural tipping point is crossed, log a Lightweight Architectural Decision Record in `memory.md` summarizing the new structural boundary and trade-off.
|
|
51
|
+
4. **Phase C — Feature Implementation (Inner TDD)**: Only once the architecture cleanly accommodates the new capability, write the failing micro-test and implement the feature.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 5. Architectural Fitness Functions (Automated Tripwires)
|
|
56
|
+
|
|
57
|
+
Prevent AI-generated code rot using automated fitness functions integrated into linting and continuous verification:
|
|
58
|
+
- **File Length Gates**: Maximum 250–300 lines per file (ESLint `max-lines`).
|
|
59
|
+
- **Function Length Gates**: Maximum 20–30 lines per function (ESLint `max-lines-per-function`).
|
|
60
|
+
- **Dependency Direction Gates**: Enforce unidirectional import rules (e.g. `import/no-restricted-paths`, `dependency-cruiser`, `ArchUnit`) ensuring domain core never imports infrastructure or transport adapters.
|
|
61
|
+
- **Complexity Budgets**: Enforce cyclomatic complexity limits (maximum 10 per function).
|
|
62
|
+
If an AI attempt to add code violates any fitness function, the build fails immediately, blocking completion until the architecture is refactored.
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
# Cloud-Native 12-Factor Standards (2026 Edition)
|
|
2
|
-
|
|
3
|
-
> **Core Mandate:** Enforce stateless isolates, OpenTelemetry (OTel) observability, API-first design, fast startup, and graceful disposal on SIGTERM across all execution runtimes.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Stateless Isolates & Shared-Nothing
|
|
8
|
-
|
|
9
|
-
- Application processes must be strictly stateless and share nothing.
|
|
10
|
-
- Any persistent state must reside in external, managed backing services (relational databases, document stores, distributed caches, object storage).
|
|
11
|
-
- User sessions and conversational state must never be held in local process memory.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 2. OpenTelemetry (OTel) Standardization
|
|
16
|
-
|
|
17
|
-
- Standardize exclusively on open-source **OpenTelemetry** across all language runtimes.
|
|
18
|
-
- Export traces, metrics, and logs in vendor-neutral **OTLP (OpenTelemetry Protocol)** format over gRPC (port 4317) or HTTP (port 4318) to an OpenTelemetry Collector.
|
|
19
|
-
- Propagate distributed trace context across service boundaries using standard W3C `traceparent` and `tracestate` headers.
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 3. Disposability & Graceful Shutdown
|
|
24
|
-
|
|
25
|
-
All application processes and containers must handle graceful termination:
|
|
26
|
-
- Trap operating system `SIGTERM` and `SIGINT` signals.
|
|
27
|
-
- Cease accepting new inbound HTTP/gRPC requests immediately upon signal receipt.
|
|
28
|
-
- Drain active, in-flight connections within a bounded timeout window (e.g. 10 seconds).
|
|
29
|
-
- Gracefully flush telemetry buffers, terminate background workers, and close database/cache connection pools cleanly before exiting with code 0:
|
|
30
|
-
|
|
31
|
-
```mermaid
|
|
32
|
-
flowchart TD
|
|
33
|
-
subgraph GracefulShutdown["Graceful Shutdown Flow (Universal / Agnostic)"]
|
|
34
|
-
Sig["onSignal (SIGTERM | SIGINT)"] --> S1["1. Set health check probe to UNHEALTHY (drain LB)"]
|
|
35
|
-
S1 --> S2["2. Stop server listening for new connections"]
|
|
36
|
-
S2 --> S3["3. Wait for in-flight requests (timeout: 10s)"]
|
|
37
|
-
S3 --> S4["4. Close database and cache connection pools"]
|
|
38
|
-
S4 --> S5["5. Flush OpenTelemetry trace & log buffers"]
|
|
39
|
-
S5 --> S6["6. Terminate process with exit code 0"]
|
|
40
|
-
end
|
|
41
|
-
```
|
|
1
|
+
# Cloud-Native 12-Factor Standards (2026 Edition)
|
|
2
|
+
|
|
3
|
+
> **Core Mandate:** Enforce stateless isolates, OpenTelemetry (OTel) observability, API-first design, fast startup, and graceful disposal on SIGTERM across all execution runtimes.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Stateless Isolates & Shared-Nothing
|
|
8
|
+
|
|
9
|
+
- Application processes must be strictly stateless and share nothing.
|
|
10
|
+
- Any persistent state must reside in external, managed backing services (relational databases, document stores, distributed caches, object storage).
|
|
11
|
+
- User sessions and conversational state must never be held in local process memory.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. OpenTelemetry (OTel) Standardization
|
|
16
|
+
|
|
17
|
+
- Standardize exclusively on open-source **OpenTelemetry** across all language runtimes.
|
|
18
|
+
- Export traces, metrics, and logs in vendor-neutral **OTLP (OpenTelemetry Protocol)** format over gRPC (port 4317) or HTTP (port 4318) to an OpenTelemetry Collector.
|
|
19
|
+
- Propagate distributed trace context across service boundaries using standard W3C `traceparent` and `tracestate` headers.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 3. Disposability & Graceful Shutdown
|
|
24
|
+
|
|
25
|
+
All application processes and containers must handle graceful termination:
|
|
26
|
+
- Trap operating system `SIGTERM` and `SIGINT` signals.
|
|
27
|
+
- Cease accepting new inbound HTTP/gRPC requests immediately upon signal receipt.
|
|
28
|
+
- Drain active, in-flight connections within a bounded timeout window (e.g. 10 seconds).
|
|
29
|
+
- Gracefully flush telemetry buffers, terminate background workers, and close database/cache connection pools cleanly before exiting with code 0:
|
|
30
|
+
|
|
31
|
+
```mermaid
|
|
32
|
+
flowchart TD
|
|
33
|
+
subgraph GracefulShutdown["Graceful Shutdown Flow (Universal / Agnostic)"]
|
|
34
|
+
Sig["onSignal (SIGTERM | SIGINT)"] --> S1["1. Set health check probe to UNHEALTHY (drain LB)"]
|
|
35
|
+
S1 --> S2["2. Stop server listening for new connections"]
|
|
36
|
+
S2 --> S3["3. Wait for in-flight requests (timeout: 10s)"]
|
|
37
|
+
S3 --> S4["4. Close database and cache connection pools"]
|
|
38
|
+
S4 --> S5["5. Flush OpenTelemetry trace & log buffers"]
|
|
39
|
+
S5 --> S6["6. Terminate process with exit code 0"]
|
|
40
|
+
end
|
|
41
|
+
```
|