azcodr 1.3.0 → 1.5.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.
Files changed (72) hide show
  1. package/.agents/hooks.json.example +42 -0
  2. package/.agents/mcp_config.json.example +24 -0
  3. package/.agents/scripts/safety_guard.sh +16 -0
  4. package/.agents/scripts/verify_completion.sh +13 -0
  5. package/.agents/skills/agentic-architect/SKILL.md +15 -8
  6. package/.agents/skills/agentic-architect/references/agents_md_template.md +6 -3
  7. package/.agents/skills/agentic-architect/references/skill_architecture_inquiry.md +1 -1
  8. package/.agents/skills/agentic-architect/references/skill_template.md +2 -1
  9. package/.agents/skills/agentic-architect/scripts/validate_agentic_configs.sh +189 -6
  10. package/.agents/skills/clean-code-refactor/SKILL.md +6 -6
  11. package/.agents/skills/compliance-audit/SKILL.md +1 -1
  12. package/.agents/skills/lets-build/SKILL.md +22 -7
  13. package/.agents/skills/lets-build/references/architecture_interview_matrix.md +8 -2
  14. package/.agents/skills/lets-build/references/hexagonal_bootstrap_scaffolds.md +53 -6
  15. package/.agents/skills/lets-build/references/project_readme_template.md +4 -4
  16. package/.agents/skills/lets-build/scripts/bootstrap_workspace.sh +181 -36
  17. package/.agents/skills/product-analyst/SKILL.md +13 -2
  18. package/.agents/skills/relentless-questioner/SKILL.md +13 -5
  19. package/.agents/skills/relentless-questioner/references/adaptive_question_trees.md +18 -0
  20. package/.gitignore +2 -0
  21. package/AGENTS.md +25 -40
  22. package/README.md +27 -40
  23. package/bin/azcodr.js +9 -4
  24. package/docs/rules/agentic_configuration.md +123 -32
  25. package/docs/rules/api_architecture.md +179 -0
  26. package/docs/rules/caching.md +30 -13
  27. package/docs/rules/cloud_native.md +10 -12
  28. package/docs/rules/cqrs.md +203 -0
  29. package/docs/rules/database_design.md +125 -0
  30. package/docs/rules/database_operations.md +56 -14
  31. package/docs/rules/design_patterns.md +18 -11
  32. package/docs/rules/devops_ci_cd.md +76 -0
  33. package/docs/rules/domain_driven_design.md +17 -13
  34. package/docs/rules/feature_flags.md +21 -4
  35. package/docs/rules/frontend_architecture.md +157 -0
  36. package/docs/rules/multitenancy_architecture.md +98 -0
  37. package/docs/rules/product_ownership.md +22 -27
  38. package/docs/rules/relentless_questioning.md +4 -0
  39. package/docs/rules/requirements_engineering.md +16 -14
  40. package/docs/rules/security_compliance.md +53 -0
  41. package/docs/rules/server_driven_ui.md +20 -3
  42. package/docs/rules/test_driven_development.md +119 -62
  43. package/docs/rules/type_safety.md +65 -0
  44. package/docs/rules/ui_ux_architecture.md +33 -30
  45. package/docs/rules/workflow_state_machines.md +20 -3
  46. package/lib/scaffold.js +117 -5
  47. package/memory.md +12 -131
  48. package/package.json +2 -2
  49. package/docs/rules/accessibility.md +0 -31
  50. package/docs/rules/advanced_api_patterns.md +0 -104
  51. package/docs/rules/api_versioning.md +0 -113
  52. package/docs/rules/application_security.md +0 -23
  53. package/docs/rules/architecture_decision_records.md +0 -42
  54. package/docs/rules/compliance.md +0 -25
  55. package/docs/rules/container_infrastructure.md +0 -32
  56. package/docs/rules/continuous_deployment.md +0 -24
  57. package/docs/rules/continuous_integration.md +0 -20
  58. package/docs/rules/continuous_learning.md +0 -29
  59. package/docs/rules/database_integrity.md +0 -80
  60. package/docs/rules/database_migrations.md +0 -41
  61. package/docs/rules/database_performance.md +0 -44
  62. package/docs/rules/database_transactions.md +0 -81
  63. package/docs/rules/devsecops.md +0 -33
  64. package/docs/rules/multitenancy_isolation.md +0 -88
  65. package/docs/rules/react.md +0 -78
  66. package/docs/rules/rest_api_conventions.md +0 -46
  67. package/docs/rules/tenant_dynamic_schemas.md +0 -88
  68. package/docs/rules/tenant_pluggable_logic.md +0 -59
  69. package/docs/rules/test_isolation.md +0 -26
  70. package/docs/rules/typescript.md +0 -55
  71. package/docs/rules/ui_navigation.md +0 -20
  72. package/docs/rules/workspace_isolation.md +0 -25
@@ -1,6 +1,6 @@
1
- # Test-Driven Development (London School TDD) & Agile Domain Lifecycle
1
+ # Test-Driven Development (London School TDD) & Test Isolation Standards
2
2
 
3
- > **Core Mandate:** Drive all features through the non-negotiable 5-Phase Agile Domain Lifecycle: Requirements ➔ Domain Analysis ➔ Outer Acceptance Test (RED) ➔ Inner Unit Test (RED-GREEN-REFACTOR) ➔ Outer Verification (GREEN). Never deviate from this sequence.
3
+ > **Core Mandate:** Drive all features through the non-negotiable 5-Phase Agile Domain Lifecycle (Outside-In Double-Loop TDD, Uncle Bob's 3 Laws), enforcing transactional database rollback per test, zero-sleep determinism, and non-negotiable 100.00% statement, branch, and function coverage gates.
4
4
 
5
5
  ---
6
6
 
@@ -8,57 +8,42 @@
8
8
 
9
9
  Every functional increment, feature, or architectural modification must traverse this unbroken sequence. Writing code out of order (e.g. coding before tests, or testing before domain analysis) is strictly prohibited.
10
10
 
11
- ```
12
- ┌────────────────────────────────────────────────────────────────────────────────────────┐
13
- │ THE NON-NEGOTIABLE AGILE DOMAIN LIFECYCLE │
14
- └────────────────────────────────────────────────────────────────────────────────────────┘
15
-
16
- [Phase 1: Requirements Engineering]
17
- │ - Decompose user prompt into INVEST user stories.
18
- │ - Author executable Gherkin Given-When-Then criteria.
19
- │ - Define Out-of-Scope non-goals and edge case status code matrix.
20
- ▼
21
- [Phase 2: Tactical Domain Analysis]
22
- │ - Discover and enforce Ubiquitous Language terms.
23
- │ - Map Bounded Contexts, Aggregate Roots, and Value Objects.
24
- │ - Codify explicit business invariants that state mutations must protect.
25
- ▼
26
- [Phase 3: Outer-Loop Acceptance Test (RED)]
27
- │ - Write failing end-to-end acceptance or contract test:
28
- │ * Frontend: Component/UI user interaction assertion (Playwright / testing library).
29
- │ * Backend: Black-box HTTP API contract test (Supertest/OpenAPI).
30
- │ - Verify the test FAILS for the expected reason (RED proof).
31
- ▼
32
- [Phase 4: Inner-Loop TDD & Collaborator Discovery (RED-GREEN-REFACTOR)]
33
- │ - Outer test discovers required collaborators (Use Cases, Ports, Domain Entities).
34
- │ - For each collaborator:
35
- │ 1. RED: Write failing unit test asserting domain invariants.
36
- │ 2. GREEN: Write minimal production code to pass.
37
- │ 3. REFACTOR: Eliminate duplication, enforce SLAP, CQS, Clean Code.
38
- ▼
39
- [Phase 5: Outer Acceptance Resolution & Definition of Done]
40
- - Run outer acceptance test: verifies GREEN without altering the test assertion.
41
- - Run cross-package boundary smoke tests (reverse proxy, sockets, LAN interfaces).
42
- - Verify 100.00% test coverage gate across all packages.
43
- - Pass Definition of Done (DoD) checklist.
11
+ ```mermaid
12
+ flowchart TD
13
+ P1["Phase 1: Requirements Engineering<br/>• INVEST stories & Gherkin criteria<br/>• Out-of-scope non-goals & status matrix"]
14
+ P2["Phase 2: Tactical Domain Analysis<br/>• Ubiquitous Language & Bounded Contexts<br/>• Aggregate Roots & Business Invariants"]
15
+ P3["Phase 3: Outer Acceptance Test (RED)<br/>• Failing UI component or API route test<br/>• Verifies failure for expected reason"]
16
+ P4["Phase 4: Inner TDD & Collaborator Discovery (RED-GREEN-REFACTOR)<br/>• Discovers Use Cases & Ports<br/>• Nano-cycles with Uncle Bob's 3 Laws"]
17
+ P5["Phase 5: Outer Verification & Proof (GREEN)<br/>• Outer test passes with zero regressions<br/>• 100.00% coverage & boundary smoke verification"]
18
+
19
+ P1 --> P2 --> P3 --> P4 --> P5
44
20
  ```
45
21
 
46
22
  ---
47
23
 
48
- ## 2. Outside-In TDD (London School) Double Loop
24
+ ## 2. The London School Double-Loop TDD Workflow
49
25
 
50
26
  Drive all user-facing features from the outermost interface inward:
51
27
 
52
- ```
53
- [Outer Loop: Acceptance / Contract Test (RED)]
54
- │
55
- ▼
56
- [Inner Loop: Unit Test Collaborator (RED)] ──► [Implement Minimal Code (GREEN)] ──► [Refactor (REFACTOR)]
57
- │ │
58
- └──────────────────────── Repeat Inner Loop until Done ◄────────────────────────────┘
59
- │
60
- ▼
61
- [Outer Loop: Acceptance / Contract Test (GREEN)] ──► [Outer Refactor]
28
+ ```mermaid
29
+ flowchart TD
30
+ subgraph OuterLoop ["Outer Loop (Acceptance / Contract Test)"]
31
+ O_RED["Outer Acceptance Test (RED)"]
32
+ O_GREEN["Outer Acceptance Test (GREEN)"]
33
+ O_REF["Outer Refactor & Proof"]
34
+ end
35
+
36
+ subgraph InnerLoop ["Inner Loop (Unit Test & Collaborator TDD)"]
37
+ I_RED["Unit Test Collaborator (RED)"]
38
+ I_GREEN["Implement Minimal Code (GREEN)"]
39
+ I_REF["Refactor under Green (REFACTOR)"]
40
+
41
+ I_RED --> I_GREEN --> I_REF
42
+ I_REF -.->|"Next Micro-Assertion"| I_RED
43
+ end
44
+
45
+ O_RED --> I_RED
46
+ I_REF --> O_GREEN --> O_REF
62
47
  ```
63
48
 
64
49
  1. **Outer Acceptance / Contract Test First**: Every feature begins with a failing outer acceptance test:
@@ -81,13 +66,9 @@ Deviating from this lifecycle introduces catastrophic defects and architectural
81
66
  | **Skipping Domain Analysis** | Hallucinated entities, missing business invariants, wrong data models. | "The Toy Prototype Blunder": Foreign key string inputs, unvalidated states, costly migrations. |
82
67
  | **Writing Code Before Tests** | Untested edge cases, unfalsifiable code, confirmation bias in test design. | Hidden bugs in production, regressions during refactoring, brittle codebases. |
83
68
  | **Skipping Outer Acceptance Tests** | In-memory unit tests pass, but user interactions and network routing fail. | "The In-Memory Supertest Illusion": App says "Offline/Connecting" while 100% unit tests pass. |
69
+ | **Dropping the UI in Fullstack TDD** | Developer plunges into internal domain units, leaving the application headless with no web UI. | "The Headless Fallacy": User requests a fullstack web app but receives pure headless backend libraries. |
84
70
  | **Skipping the Refactor Phase** | Technical debt accumulates immediately behind green tests. | Code rot, duplicated logic, bloated monolithic functions (> 30 lines), violated DRY/SLAP. |
85
71
 
86
- ### The Immutable Three Laws of TDD (Uncle Bob & Kent Beck):
87
- 1. **First Law:** You are not allowed to write any production code unless it is to make a single failing unit or acceptance test pass.
88
- 2. **Second Law (Strict Incremental Boundary):** You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
89
- 3. **Third Law (Minimal Production Code):** You are not allowed to write any more production code than is sufficient to pass the one currently failing test.
90
-
91
72
  ---
92
73
 
93
74
  ## 4. The Batch-Test Anti-Pattern & The Incremental Nano-Cycle
@@ -111,18 +92,94 @@ Every collaborator discovered in Phase 4 must progress through micro-cycles of o
111
92
  ## 5. Ping-Pong Pair Programming Protocol with AI
112
93
 
113
94
  When pairing with the human developer, operate in true **Ping-Pong TDD**:
95
+
96
+ ```mermaid
97
+ sequenceDiagram
98
+ autonumber
99
+ actor A as Partner A (Driver/Human)
100
+ participant S as Test Runner
101
+ actor B as Partner B (Navigator/AI)
102
+
103
+ A->>S: Writes 1 micro-test assertion (RED)
104
+ S-->>A: Displays verified failure output
105
+ B->>S: Writes minimal code to pass (GREEN)
106
+ S-->>B: Displays verified pass
107
+ Note over A,B: Both refactor under green (REFACTOR)
108
+ Note over A,B: Roles swap; repeat for next behavior
114
109
  ```
115
- ┌─────────────────────────────────────────────────────────────┐
116
- │ PING-PONG PAIR PROGRAMMING │
117
- │ │
118
- │ Turn 1 [Partner A]: Writes ONE micro-test assertion (RED) │
119
- │ Turn 2 [System]: Runs test & displays verified failure │
120
- │ Turn 3 [Partner B]: Writes MINIMAL code to pass (GREEN) │
121
- │ Turn 4 [System]: Runs test & displays verified pass │
122
- │ Turn 5 [Both]: Refactors under green (REFACTOR) │
123
- │ Turn 6: Roles swap; repeat for next behavior │
124
- └─────────────────────────────────────────────────────────────┘
125
- ```
110
+
126
111
  - **Collaborative Steering**: The human developer can write the test while the AI writes the minimal pass, or the AI can present each micro-test and await confirmation before implementing.
127
112
  - **Continuous Alignment**: Design and data structures emerge organically through mutual feedback rather than monolithic code dumps.
128
113
 
114
+ ---
115
+
116
+ ## 6. Test Isolation & Determinism
117
+
118
+ - **Transactional Rollback per Integration Test**:
119
+ - Every integration test that interacts with persistence must execute within a scoped transaction that is rolled back upon test completion (`afterEach` rollback) or use ephemeral, disposable database isolates. Never leave mutated rows that pollute subsequent tests.
120
+ - **Deterministic Test Data Factories**:
121
+ - Utilize strongly-typed test data factories (`buildUser()`, `buildOrder()`) with randomized unique identifiers rather than hardcoded magic strings or fixed database IDs.
122
+ - **Zero Sleep / Flakiness Elimination**:
123
+ - Strictly forbid arbitrary `sleep()` or timeout pauses in tests.
124
+ - Rely exclusively on deterministic condition polling (`waitFor(condition)`) or reactive event promises to eliminate test flakiness.
125
+
126
+ ---
127
+
128
+ ## 7. Mandatory 100.00% Test Coverage Thresholds
129
+
130
+ - **Strict Coverage Thresholds**: Maintain line, function, branch, and statement test coverage at **100.00%** across all backend domain logic, adapters, contracts, and frontend suites. Strictly enforce 100% threshold failure gates in CI pipelines (`scripts/test_coverage.js`).
131
+ - **Exhaustive Status Codes & Error Branches**: Explicitly test all HTTP/gRPC response codes:
132
+ - Success: `200 OK`, `201 Created`, `204 No Content`
133
+ - Client Errors: `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, `409 Conflict`, `422 Unprocessable Entity`, `429 Too Many Requests`
134
+ - Server Failures: `500 Internal Server Error`, `503 Service Unavailable`
135
+ - **UI Interaction States & Edge Cases**: Fully assert all presentation states (loading spinners, disabled controls, error banners, success feedback, empty states) across suites.
136
+
137
+ ---
138
+
139
+ ## 8. Headless UI Testing Architecture for Autonomous Agents
140
+
141
+ Autonomous AI coding agents operate without human eyesight. To verify user interfaces deterministically without manual browser clicking, projects with UI interfaces must enforce the **4-Tier Headless UI Testing Pyramid**:
142
+
143
+ ```mermaid
144
+ flowchart TD
145
+ T4["Tier 4: Headless Playwright E2E<br/>(Full multi-page browser journeys, Chromium CLI)"]
146
+ T3["Tier 3: Automated A11y Gates (axe-core)<br/>(WCAG 2.2 AA audits with zero human eyesight)"]
147
+ T2["Tier 2: Network Isolation via MSW<br/>(Deterministic HTTP mocking: loading, error, empty, success)"]
148
+ T1["Tier 1: Behavioral Component Testing (@testing-library)<br/>(Accessible role queries, user-event keyboard/mouse)"]
149
+
150
+ T4 --> T3 --> T2 --> T1
151
+ ```
152
+
153
+ ### 8.1. Behavioral Component Testing (@testing-library + jsdom/happy-dom)
154
+ - **Test Behavior, Not Implementation**: Never assert component internal state, hook variables, or private methods. Assert what the user experiences.
155
+ - **Strict Accessible Role-Based Queries**:
156
+ - *Mandatory:* `screen.getByRole('button', { name: /submit/i })`, `screen.getByRole('heading', { level: 1 })`, `screen.getByLabelText(/email/i)`.
157
+ - *Prohibited:* `container.querySelector('.btn-primary')`, `getByTestId('submit-btn')` (data-testid is a banned crutch for poor semantic accessibility).
158
+ - **Realistic User Events**: Always use `@testing-library/user-event` rather than synthetic `fireEvent` to accurately simulate browser focus, keypress, typing, and click sequences.
159
+
160
+ ### 8.2. Network Isolation via Mock Service Worker (MSW)
161
+ - Never mock client fetch/HTTP clients with ad-hoc mock objects (`vi.fn()`).
162
+ - Intercept requests at the network layer using **MSW**:
163
+ ```typescript
164
+ // Deterministic network boundary simulation
165
+ http.get('/api/v1/orders', () => HttpResponse.json(mockOrders))
166
+ ```
167
+ - **The 4 Universal UI Presentation States**: Component tests must explicitly assert:
168
+ 1. *Loading State:* Accessible spinner / skeleton is rendered while request is in flight.
169
+ 2. *Success State:* Data grid / list renders items with correct semantic markup.
170
+ 3. *Error State:* RFC 7807 error banner renders with retry button when API returns `500` or `422`.
171
+ 4. *Empty State:* Meaningful empty-state message and CTA when API returns `[]`.
172
+
173
+ ### 8.3. Automated Headless Accessibility Gates (axe-core)
174
+ - Every component test suite must execute automated accessibility checks using `axe-core` (`vitest-axe` or `@axe-core/playwright`):
175
+ ```typescript
176
+ const { container } = render(<OrderDetailsModal orderId="ord_123" />);
177
+ const results = await axe(container);
178
+ expect(results).toHaveNoViolations();
179
+ ```
180
+ - Fails the test automatically on missing ARIA labels, invalid heading hierarchies, contrast defects, or unlinked form labels without requiring human eyesight.
181
+
182
+ ### 8.4. End-to-End Headless Browser Automation (Playwright)
183
+ - For critical user journeys (authentication, checkout, resource creation):
184
+ - Run headless Chromium in CLI/CI: `npx playwright test`.
185
+ - Configure automated forensic captures on failure: screenshots, trace files, and videos saved to `test-results/` for immediate agent inspection.
@@ -0,0 +1,65 @@
1
+ # Static Type Safety & Sound Type Systems
2
+
3
+ > **Core Mandate:** Enforce maximum compiler strictness, branded nominal typing for domain identifiers, strict prohibition of untyped escape hatches, and automated pre-commit quality guardrails across polyglot implementations.
4
+
5
+ ---
6
+
7
+ ## 1. The YAGNI Gate: Sound Types vs. Type-Level Acrobatics
8
+
9
+ Type systems exist to prove program correctness and eliminate entire classes of runtime errors. **Never compromise static type safety with `any` escape hatches, but avoid premature type-level metaprogramming acrobatics that obscure domain intent.**
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ subgraph TypeSafetyGate["Type Safety YAGNI Gate"]
14
+ B1["1. Simple Baseline (Day 1)<br/>• Strict compiler flags enabled with zero compilation warnings<br/>• Concrete interfaces, records, dataclasses, and structs<br/>• Zero any, Any, or raw Object escape hatches"]
15
+ B2["2. Anti-Triggers (Forbidden)<br/>• Bypassing the compiler via any, as unknown as T, or casts<br/>• Deep recursive type-gymnastics where a simple interface solves it<br/>• Primitive Obsession: passing raw string for all domain IDs"]
16
+ B3["3. The Tipping Point (Graduation)<br/>• Domain Identifiers: Use Branded/Nominal types when multiple entity IDs risk mix-ups<br/>• System Boundaries: Use fail-fast schema validation (Zod, Serde, Pydantic) on untrusted inputs"]
17
+ B1 -->|Forbidden if compiler bypassed| B2
18
+ B1 -->|Triggered by domain safety & boundary parsing| B3
19
+ end
20
+ ```
21
+
22
+ ---
23
+
24
+ ## 2. Maximum Compiler Strictness Across Polyglot Stacks
25
+
26
+ Regardless of the execution language chosen for an adapter, service, or CLI, enforce maximum compiler rigor to eliminate runtime null pointer exceptions, unhandled type cases, and memory errors at compile time:
27
+
28
+ - **TypeScript**: Enable all strict compiler flags (`strict: true`, `noImplicitAny: true`, `strictNullChecks: true`, `noUncheckedIndexedAccess: true`).
29
+ - **Python**: Enforce strict type checking (`mypy --strict` or `pyright` in strict mode).
30
+ - **Rust**: Enable `#![deny(clippy::all)]` and `#![deny(missing_docs)]` with zero `unsafe` blocks.
31
+ - **Go**: Enable comprehensive static analysis (`golangci-lint` with `errcheck`, `govet`, `staticcheck`).
32
+ - **Java**: Enable `-Werror -Xlint:all`, enforce `@NonNull` contracts or the Checker Framework.
33
+ - **C#**: Enable `<Nullable>enable</Nullable>` and `<TreatWarningsAsErrors>true</TreatWarningsAsErrors>`.
34
+
35
+ ---
36
+
37
+ ## 3. Branded Nominal Typing & Primitive Obsession Elimination
38
+
39
+ Prevent accidental mixing of raw primitive identifiers (e.g. passing an arbitrary `string` representing a `TenantId` where a `UserId` is expected) by enforcing nominal types across all supported languages:
40
+
41
+ ```mermaid
42
+ classDiagram
43
+ class NominalIdentifierPattern {
44
+ <<Polyglot Implementations>>
45
+ }
46
+ note for NominalIdentifierPattern "Rust: struct TenantId(String); struct UserId(String);<br/>Go: type TenantId string; type UserId string<br/>TypeScript: type TenantId = Brand<string, 'TenantId'>;<br/>Python: TenantId = NewType('TenantId', str)<br/>Java: record TenantId(String value) {}<br/>C#: readonly record struct TenantId(string Value);"
47
+ ```
48
+
49
+ Domain functions must accept and return branded types rather than raw primitive strings or integers.
50
+
51
+ ---
52
+
53
+ ## 4. Strict Prohibition of Untyped Escape Hatches
54
+
55
+ - **Zero Tolerance for Unsound Types**: Strictly prohibit `any` in TypeScript, raw `interface{}` / `any` without type assertion checks in Go, raw `Any` in Python, or unchecked casts in Java/Rust/C#.
56
+ - **Runtime Validation at Boundaries**: External payloads (network requests, message queues, disk files) must be parsed and narrowed into strongly-typed domain structures before passing to application services (e.g. via Zod in TS, Pydantic in Python, Serde in Rust, Jackson/Record validation in Java).
57
+ - **Commit Guardrails**: Enforce Conventional Commits via commit linters. Never bypass pre-commit hooks running static type checking, formatting, and linters.
58
+
59
+ ---
60
+
61
+ ## 5. Clean Import Hygiene & Relative Traversal Elimination
62
+
63
+ - **Path Alias Mandate**: In languages supporting path aliases (TypeScript, Python packages, Go modules), configure root module resolution (e.g. `@/*` mapped to `./src/*`) to prevent brittle relative coupling.
64
+ - **Strict Prohibition of Deep Relative Traversal**: Never use deep relative traversals (`../../../..`, `../../..`, `../..`) across layers or contexts. Deep relative paths create fragile coupling, impair refactoring, and obscure domain layer boundaries.
65
+ - **Scope of Sibling Imports**: Local relative imports (`./file`) are permitted only for immediate siblings within the identical directory. Any import traversing up a directory hierarchy or crossing architectural boundaries (domain, ports, adapters, components, context) MUST resolve via root package paths or aliases.
@@ -10,14 +10,16 @@ A catastrophic software defect occurs when design architecture is not triaged up
10
10
 
11
11
  Before a single UI component or view is built, every interface increment must pass the **7-Pillar Design Architecture Triage Gate**:
12
12
 
13
- ```
14
- 1. ROLE & IDENTITY TRIAGE ──► Who is the user? What is their exact operational domain and boundary?
15
- 2. INFORMATION ARCHITECTURE ──► What is the hierarchy? Persistent Shell vs. Dynamic Canvas?
16
- 3. EXPERIENCE DUALITY ──► Operator Enterprise Workspace (dense) vs. Member Consumer Portal (simple)?
17
- 4. NAVIGATION & WAYFINDING ──► Collapsible sidebar, breadcrumbs, command palette (Cmd+K), mobile drawer?
18
- 5. STATE & URL SYNCHRONIZATION ──► Deep-linkable search params (?tab=, ?q=, ?page=, ?modal=)?
19
- 6. ACCESS & ROUTE PROTECTION ──► Strict route guards (<ProtectedRoute>), role redirection, 403 handling?
20
- 7. ACCESSIBILITY & FEEDBACK ──► WCAG 2.2 AA, focus trapping, ARIA live regions, zero browser-native alerts?
13
+ ```mermaid
14
+ flowchart TD
15
+ P1["1. Role & Identity Triage<br/>Who is the user? Operational domain & boundary"]
16
+ P2["2. Information Architecture<br/>Hierarchy: Persistent Shell vs. Dynamic Canvas"]
17
+ P3["3. Experience Duality<br/>Operator Enterprise Workspace (dense) vs. Member Consumer Portal (simple)"]
18
+ P4["4. Navigation & Wayfinding<br/>Collapsible sidebar, breadcrumbs, command palette Cmd+K, mobile drawer"]
19
+ P5["5. State & URL Synchronization<br/>Deep-linkable search params (?tab=, ?q=, ?page=, ?modal=)"]
20
+ P6["6. Access & Route Protection<br/>Route guards, role redirection, 403 handling"]
21
+ P7["7. Accessibility & Feedback<br/>WCAG 2.2 AA, focus trapping, ARIA live regions, zero native alerts"]
22
+ P1 --> P2 --> P3 --> P4 --> P5 --> P6 --> P7
21
23
  ```
22
24
 
23
25
  ---
@@ -26,27 +28,28 @@ Before a single UI component or view is built, every interface increment must pa
26
28
 
27
29
  The application interface is strictly divided into two distinct anatomical zones:
28
30
 
29
- ```
30
- +----------------------------------------------------------------------------------------------------+
31
- | PERSISTENT GLOBAL HEADER |
32
- | [Brand / Logo] | [Organization Context Switcher] | [Command Palette Cmd+K] | [Alerts] | [User Menu]|
33
- +------------------------------------+---------------------------------------------------------------+
34
- | PERSISTENT OPERATOR SIDEBAR | DYNAMIC VIEWPORT CANVAS |
35
- | (Collapsible to 64px Icon Rail) | |
36
- | | 1. CONTEXTUAL BREADCRUMBS |
37
- | - Overview (Dashboard) | Home > Resources > Resource Alpha > Details |
38
- | - Operations (Catalogs, Resources) | ------------------------------------------------------------- |
39
- | - Transactions (Orders, Invoices) | 2. PAGE HEADER & PRIMARY ACTION CTA |
40
- | - Financials (Ledger, Settlements) | [Page Title] [Filter] [+ Primary Action CTA] |
41
- | - Services (Requests, Tickets) | ------------------------------------------------------------- |
42
- | - Settings (Team, Roles, Org) | 3. URL-SYNCHRONIZED TABS & SEARCH BAR |
43
- | ---------------------------------- | [Active (12)] [Draft (2)] [Archived (0)] [Search...] |
44
- | [System Health Badge] | ------------------------------------------------------------- |
45
- | [Collapse / Expand Toggle Button] | 4. DATA PRESENTATION CANVAS |
46
- | | (Data Tables, Metric Grids, Detail Drawers, Dialogs) |
47
- +------------------------------------+---------------------------------------------------------------+
48
- | PERSISTENT STATUS / FOOTER (System Context, Active Role Indicator, Accessible Live Regions) |
49
- +----------------------------------------------------------------------------------------------------+
31
+ ```mermaid
32
+ flowchart TD
33
+ subgraph PersistentAppShell["Persistent Application Shell"]
34
+ Header["Persistent Global Header<br/>[Brand / Logo] | [Org Switcher] | [Command Palette Cmd+K] | [Alerts] | [User Profile]"]
35
+
36
+ subgraph BodyLayout["Viewport Split"]
37
+ Sidebar["Persistent Operator Sidebar<br/>(Collapsible to 64px Icon Rail)<br/>• Overview (Dashboard)<br/>• Operations (Catalogs, Resources)<br/>• Transactions (Orders, Invoices)<br/>• Financials (Ledger, Settlements)<br/>• Services (Requests, Tickets)<br/>• Settings (Team, Roles, Org)<br/>• Collapse / Expand Toggle"]
38
+
39
+ subgraph DynamicCanvas["Dynamic Viewport Canvas"]
40
+ Breadcrumb["1. Contextual Breadcrumbs<br/>Home > Resources > Details"]
41
+ PageHeader["2. Page Header & Primary Action CTA<br/>[Page Title] [Filter] [+ Primary Action CTA]"]
42
+ Tabs["3. URL-Synchronized Tabs & Search Bar<br/>[Active (12)] [Draft (2)] [Archived (0)] [Search...]"]
43
+ Content["4. Data Presentation Canvas<br/>(Data Tables, Metric Grids, Detail Drawers, Dialogs)"]
44
+ Breadcrumb --> PageHeader --> Tabs --> Content
45
+ end
46
+ Sidebar ~~~ DynamicCanvas
47
+ end
48
+
49
+ Footer["Persistent Status / Footer (System Context, Active Role Indicator, Accessible Live Regions)"]
50
+
51
+ Header --> BodyLayout --> Footer
52
+ end
50
53
  ```
51
54
 
52
55
  ### 2.1. The Persistent Shell (Never Re-rendered Across Page Navigations)
@@ -132,7 +135,7 @@ To prevent confusing operators with consumer simplicity and overwhelming consume
132
135
 
133
136
  ## 6. Bidirectional URL State Synchronization
134
137
 
135
- Per [`docs/rules/ui_navigation.md`](./ui_navigation.md), all view state that represents navigation, active tab, filtering, sorting, pagination, or search query must synchronize bidirectionally with URL search parameters (`useSearchParams`):
138
+ Per [`docs/rules/frontend_architecture.md`](./frontend_architecture.md), all view state that represents navigation, active tab, filtering, sorting, pagination, or search query must synchronize bidirectionally with URL search parameters (`useSearchParams`):
136
139
  1. **Tabs**: `?tab=active`, `?tab=draft`, `?tab=archived`
137
140
  2. **Filters**: `?status=ACTIVE&category=cloud`
138
141
  3. **Search Queries**: `?q=alpha`
@@ -4,7 +4,24 @@
4
4
 
5
5
  ---
6
6
 
7
- ## 1. The Fallacy of Universal Configurability
7
+ ## 1. The YAGNI Gate: Simple Enums vs. State Machines
8
+
9
+ State machine libraries, declarative transition matrices, and workflow orchestration engines introduce significant cognitive and operational weight. **Never build a state machine when a simple enum or boolean flag suffices.**
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ subgraph StateMachineGate["State Machine YAGNI Gate"]
14
+ B1["1. Simple Baseline (Day 1)<br/>• Discriminated union or enum column (status: 'PENDING' | 'DONE')<br/>• Simple guard clause in aggregate method (if (status !== 'A'))<br/>• Zero external state-machine libraries (no XState, Temporal, BPMN)"]
15
+ B2["2. Anti-Triggers (Forbidden)<br/>• Binary lifecycle flags (is_active, is_verified, archived)<br/>• Strict linear forward-only progressions without branching/rollback<br/>• Synchronous single-table mutations within one ACID transaction"]
16
+ B3["3. The Tipping Point (Graduation)<br/>• Entity has 3+ non-linear states with branching transitions, cancellations, or conditional rollbacks<br/>• Transitions require multi-step side-effects (emitting domain events, releasing authorizations)<br/>• Business/regulatory rules mandate an immutable transition audit<br/>• Durable orchestration (Temporal) justified ONLY when transitions depend on asynchronous multi-day callbacks"]
17
+ B1 -->|Forbidden if linear or binary| B2
18
+ B1 -->|Triggered by multi-step or non-linear branches| B3
19
+ end
20
+ ```
21
+
22
+ ---
23
+
24
+ ## 2. The Fallacy of Universal Configurability
8
25
 
9
26
  A common architectural anti-pattern is the **"Universal Workflow Fallacy"** (a variant of the *Inner Platform Effect*), which presumes that *every* status and state transition in a system should be dynamically configurable by end-users or tenants.
10
27
 
@@ -25,7 +42,7 @@ A common architectural anti-pattern is the **"Universal Workflow Fallacy"** (a v
25
42
 
26
43
  ---
27
44
 
28
- ## 2. State Machine Architectural Patterns
45
+ ## 3. State Machine Architectural Patterns
29
46
 
30
47
  ### Pattern A: In-Aggregate State Machine (Hard Invariants)
31
48
  Model states as **Discriminated Unions** or the GoF **State Pattern** encapsulated inside the domain entity. Public mutations must be explicit domain actions:
@@ -82,7 +99,7 @@ When a state transition requires coordination across multiple aggregates or asyn
82
99
 
83
100
  ---
84
101
 
85
- ## 3. Mandatory State Transition Audit Trail
102
+ ## 4. Mandatory State Transition Audit Trail
86
103
 
87
104
  Every state change across any entity or workflow MUST be immutably recorded in a transition log:
88
105
 
package/lib/scaffold.js CHANGED
@@ -11,7 +11,8 @@ const TEMPLATE_ITEMS = [
11
11
  'docs',
12
12
  '.agents',
13
13
  '.gitignore',
14
- '.editorconfig'
14
+ '.editorconfig',
15
+ 'LICENSE'
15
16
  ];
16
17
 
17
18
  /**
@@ -93,7 +94,7 @@ function ensureSymlink(targetDir, linkName, targetFileName, dryRun = false) {
93
94
  return true;
94
95
  } catch {
95
96
  // Fallback if environment (e.g., certain Windows configs) prevents symlink creation
96
- const sourceFile = path.join(targetDir, targetFileName);
97
+ const sourceFile = path.resolve(targetDir, targetFileName);
97
98
  if (fs.existsSync(sourceFile)) {
98
99
  fs.copyFileSync(sourceFile, linkPath);
99
100
  }
@@ -102,10 +103,29 @@ function ensureSymlink(targetDir, linkName, targetFileName, dryRun = false) {
102
103
  }
103
104
 
104
105
  /**
105
- * Ensures all bash scripts in skill directories have executable permissions (0o755).
106
+ * Ensures all bash scripts in agent and skill directories have executable permissions (0o755).
106
107
  */
107
108
  function makeScriptsExecutable(targetDir, dryRun = false) {
108
109
  const modified = [];
110
+
111
+ const agentScriptsDir = path.join(targetDir, '.agents', 'scripts');
112
+ if (fs.existsSync(agentScriptsDir) && fs.statSync(agentScriptsDir).isDirectory()) {
113
+ const files = fs.readdirSync(agentScriptsDir);
114
+ for (const file of files) {
115
+ if (file.endsWith('.sh')) {
116
+ const filePath = path.join(agentScriptsDir, file);
117
+ modified.push(filePath);
118
+ if (!dryRun) {
119
+ try {
120
+ fs.chmodSync(filePath, 0o755);
121
+ } catch {
122
+ // Non-critical if filesystem does not support POSIX permissions
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+
109
129
  const skillsDir = path.join(targetDir, '.agents', 'skills');
110
130
  if (!fs.existsSync(skillsDir)) return modified;
111
131
 
@@ -146,7 +166,13 @@ function copyTemplate(targetDir, templateDir = getTemplateDir(), options = {}) {
146
166
  }
147
167
 
148
168
  for (const item of TEMPLATE_ITEMS) {
149
- const srcPath = path.join(resolvedTemplate, item);
169
+ let srcPath = path.join(resolvedTemplate, item);
170
+ if (item === '.gitignore' && !fs.existsSync(srcPath)) {
171
+ const npmIgnorePath = path.join(resolvedTemplate, '.npmignore');
172
+ if (fs.existsSync(npmIgnorePath)) {
173
+ srcPath = npmIgnorePath;
174
+ }
175
+ }
150
176
  if (!fs.existsSync(srcPath)) continue;
151
177
 
152
178
  const destPath = path.join(resolvedTarget, item);
@@ -164,6 +190,45 @@ function copyTemplate(targetDir, templateDir = getTemplateDir(), options = {}) {
164
190
  actions.push(`symlink: agents.md -> AGENTS.md`);
165
191
  ensureSymlink(resolvedTarget, 'agents.md', 'AGENTS.md', dryRun);
166
192
 
193
+ actions.push(`symlink: GEMINI.md -> AGENTS.md`);
194
+ ensureSymlink(resolvedTarget, 'GEMINI.md', 'AGENTS.md', dryRun);
195
+
196
+ actions.push(`symlink: .cursorrules -> AGENTS.md`);
197
+ ensureSymlink(resolvedTarget, '.cursorrules', 'AGENTS.md', dryRun);
198
+
199
+ actions.push(`symlink: .windsurfrules -> AGENTS.md`);
200
+ ensureSymlink(resolvedTarget, '.windsurfrules', 'AGENTS.md', dryRun);
201
+
202
+ // GitHub Copilot harness parity
203
+ const githubDir = path.join(resolvedTarget, '.github');
204
+ if (!dryRun && !fs.existsSync(githubDir)) {
205
+ fs.mkdirSync(githubDir, { recursive: true });
206
+ }
207
+ actions.push(`symlink: .github/copilot-instructions.md -> ../AGENTS.md`);
208
+ ensureSymlink(githubDir, 'copilot-instructions.md', '../AGENTS.md', dryRun);
209
+
210
+ // Starter package.json for project scripts validation
211
+ const pkgJsonPath = path.join(resolvedTarget, 'package.json');
212
+ if (!fs.existsSync(pkgJsonPath)) {
213
+ actions.push('create: package.json');
214
+ if (!dryRun) {
215
+ const projectName = path.basename(resolvedTarget) || 'my-project';
216
+ const starterPkg = {
217
+ name: projectName,
218
+ version: '0.1.0',
219
+ private: true,
220
+ description: 'Scaffolded with azcodr enterprise architecture template',
221
+ scripts: {
222
+ test: 'node --test',
223
+ 'test:coverage': 'node --test --experimental-test-coverage',
224
+ lint: 'echo "No linter configured yet. Run /lets-build to configure toolchain."',
225
+ validate: 'bash .agents/skills/agentic-architect/scripts/validate_agentic_configs.sh'
226
+ }
227
+ };
228
+ fs.writeFileSync(pkgJsonPath, JSON.stringify(starterPkg, null, 2) + '\n', 'utf-8');
229
+ }
230
+ }
231
+
167
232
  // Ensure scripts are executable
168
233
  const inspectDir = dryRun ? resolvedTemplate : resolvedTarget;
169
234
  const scripts = makeScriptsExecutable(inspectDir, dryRun);
@@ -174,6 +239,23 @@ function copyTemplate(targetDir, templateDir = getTemplateDir(), options = {}) {
174
239
  return actions;
175
240
  }
176
241
 
242
+ /**
243
+ * Detects whether targetDir is already inside an existing Git worktree.
244
+ */
245
+ function isInsideGitWorkTree(targetDir) {
246
+ try {
247
+ const checkDir = fs.existsSync(targetDir) ? targetDir : path.dirname(targetDir);
248
+ const out = cp.execSync('git rev-parse --is-inside-work-tree', {
249
+ cwd: checkDir,
250
+ stdio: ['ignore', 'pipe', 'ignore'],
251
+ encoding: 'utf-8'
252
+ });
253
+ return out.trim() === 'true';
254
+ } catch {
255
+ return false;
256
+ }
257
+ }
258
+
177
259
  /**
178
260
  * Initializes a git repository in the target directory if not already inside one.
179
261
  */
@@ -184,12 +266,41 @@ function initGit(targetDir, options = {}) {
184
266
  const gitDir = path.join(targetDir, '.git');
185
267
  if (fs.existsSync(gitDir)) return false;
186
268
 
269
+ if (isInsideGitWorkTree(targetDir)) return false;
270
+
187
271
  if (dryRun) {
188
272
  return true;
189
273
  }
190
274
 
191
275
  try {
192
- cp.execSync('git init -q', { cwd: targetDir, stdio: 'ignore' });
276
+ try {
277
+ cp.execSync('git init -b main -q', { cwd: targetDir, stdio: 'ignore' });
278
+ } catch {
279
+ cp.execSync('git init -q', { cwd: targetDir, stdio: 'ignore' });
280
+ try {
281
+ cp.execSync('git branch -m main', { cwd: targetDir, stdio: 'ignore' });
282
+ } catch {
283
+ // Non-critical if branch rename fails
284
+ }
285
+ }
286
+
287
+ try {
288
+ cp.execSync('git add -A', { cwd: targetDir, stdio: 'ignore' });
289
+ try {
290
+ cp.execSync('git commit -q -m "chore: initial scaffold from azcodr template"', {
291
+ cwd: targetDir,
292
+ stdio: 'ignore'
293
+ });
294
+ } catch {
295
+ cp.execSync('git -c user.name="azcodr" -c user.email="azcodr@local" commit -q -m "chore: initial scaffold from azcodr template"', {
296
+ cwd: targetDir,
297
+ stdio: 'ignore'
298
+ });
299
+ }
300
+ } catch {
301
+ // Non-critical if initial commit fails
302
+ }
303
+
193
304
  return true;
194
305
  } catch {
195
306
  return false;
@@ -233,6 +344,7 @@ module.exports = {
233
344
  ensureSymlink,
234
345
  isSameCaseInsensitiveFile,
235
346
  makeScriptsExecutable,
347
+ isInsideGitWorkTree,
236
348
  initGit,
237
349
  getTemplateDir,
238
350
  TEMPLATE_ITEMS