Audit Role: Software Architect + Solutions Architect (BMAD)
Audit Date: 2026-06-07
Method: BMAD · Evolith Tracker Documentation Audit
| Technical Area | Status | Severity |
|---|---|---|
| Architecture (Progressive Monolith) | CORRECT | — |
| Bounded Contexts | CORRECT | — |
| Modular Layer Structure | CORRECT | — |
| Domain Model | CORRECT | — |
| DDD Aggregates / Entities | CORRECT | — |
| Commands / Queries (CQRS) | CORRECT | — |
| Domain Events | CORRECT | — |
| Repository Pattern | CORRECT | — |
| Transactional Outbox | CORRECT (fixed) | RESOLVED — TypeORM |
| In-Memory Service Bus | CORRECT | — |
| PostgreSQL Schema Isolation | CORRECT (resolved) | RESOLVED — T-008 tracker_* |
| Multi-Tenancy (RLS) | CORRECT | — |
| UMS Auth Integration | CORRECT | — |
| Evolith Core Integration | PARTIALLY_CORRECT | — |
| ACL (External Systems) | CORRECT | — |
| REST API Design | CORRECT | — |
| GraphQL API | OUT_OF_SCOPE (resolved) | RESOLVED — T-009 REST-only Phase 1 |
| Frontend (React Microfrontends) | CORRECT (resolved) | RESOLVED — Module Federation, T-002 |
| State Management | CORRECT | — |
| Observability | PARTIALLY_CORRECT | — |
| Docker | CORRECT (conceptual) | — |
| Kubernetes / Helm | CORRECT (conceptual) | — |
| Test Strategy | DEFINED (resolved) | RESOLVED — tracker-test-strategy.md |
| Security Specification | DEFINED (resolved) | RESOLVED — tracker-security-spec.md (7 ⊕ proposals pending) |
| CI/CD Pipeline Spec | DEFINED (resolved) | RESOLVED — tracker-cicd-spec.md (6 ⊕ proposals pending) |
| ADRs — Local | UNDERDEFINED | MEDIUM |
| ADRs — Harness | INCONSISTENT | MEDIUM |
| References in TAD | INCONSISTENT | HIGH — broken links |
The TAD correctly defines Evolith Tracker as a Progressive Monolith:
- Single NestJS deployment unit
- 5 Phase Gate bounded contexts as logical modules
- Schema-per-domain in PostgreSQL
- Extraction-ready for future distributed evolution
This aligns with Product Vision §2 ("Ecosistema de Monolitos Progresivos Multi-Tenant") and PRD Phase 1 constraint.
Verdict: CORRECT
| Bounded Context | Module | Schema | Aggregate Roots | Source |
|---|---|---|---|---|
| Discovery | @evolith/tracker-discovery |
tracker_discovery |
Initiative, Backlog, Epic, UserStory | PRD EPIC-000, Discovery DDD |
| Design | @evolith/tracker-design |
tracker_design |
TechnicalBlueprint, TechnicalContract, ADR, DataSchema | PRD EPIC-001, Design DDD |
| Construction | @evolith/tracker-construction |
tracker_construction |
ImplementationCycle, TechnicalStory, PeerReview | PRD EPIC-002, Construction DDD |
| QA | @evolith/tracker-qa |
tracker_qa |
TestCycle, TestExecution, Defect | PRD EPIC-003, QA DDD |
| Release | @evolith/tracker-release |
tracker_release |
ReleasePackage, DeploymentRecord, Environment | PRD EPIC-004, Release DDD |
| Governance | @evolith/tracker-governance |
tracker_governance |
SatelliteProduct, SDLCExecution, PhaseGateState | PRD EPIC-005, EPIC-006 |
| Artifacts | @evolith/tracker-artifacts |
tracker_artifacts |
ArtifactDefinition, ArtifactInstance, EvidenceRecord | PRD Artifacts |
| Metrics | @evolith/tracker-metrics |
tracker_metrics |
ScorecardDefinition, MetricSnapshot, DriftAlert | PRD EPIC-006 |
| Integration | @evolith/tracker-integration |
tracker_integration |
IntegrationEndpoint, SyncRecord, ACLAdapter | PRD ACLs |
Additional: tracker_audit schema for append-only audit trail — correctly scoped.
Verdict: CORRECT (9 bounded contexts, all with functional source)
Finding: Two documents define PostgreSQL schema names with different conventions:
| Document | Schema Names Used |
|---|---|
tracker-target-architecture.md (TAD) |
tracker_discovery, tracker_design, tracker_construction, tracker_qa, tracker_release, tracker_governance, tracker_artifacts, tracker_metrics, tracker_integration, tracker_audit |
c4-macro-topology-phase1.md (C4) |
schema_discovery, schema_design, schema_construction, schema_qa, schema_release |
reference/specs/design/functional-scope.md |
schema_design |
Conflicting Sources: TAD vs. C4 vs. Functional Scope Design
Impact: Implementation will use inconsistent schema names. Migration scripts will conflict.
Severity: CRITICAL
Recommendation: Adopt TAD convention (tracker_<context>) as the canonical standard — it is more recent and more explicit. Update C4 diagram and Functional Scope docs to match.
Requires Architectural Decision: YES — register in DECISIONS.md
Can auto-correct: NO (impacts C4 diagram content, which is architectural)
Status: ✅ RESOLVED (2026-06-07) — tracker_<context> adopted, registered as T-008. C4 + functional-scope (Design/Discovery, EN/ES) updated.
Finding: The TAD (Section 13 — Service Bus and Messaging) declares TypeORM as the ORM (Section 10 — Backend Stack: "TypeORM | ADR-0043 decision") but the OutboxProcessor code example uses Prisma syntax:
// INCORRECT — uses Prisma syntax in a TypeORM project
const messages = await this.prisma.outboxMessages.findMany({...});
await this.prisma.outboxMessages.update({...});Impact: Copy-paste of this code into the implementation will create a dependency on Prisma when TypeORM is declared. This will fail to compile.
Severity: HIGH
Recommendation: Replace the OutboxProcessor example with TypeORM-equivalent syntax using EntityManager or DataSource.
Can auto-correct: YES — corrected in this audit (see corrections section)
Finding:
c4-macro-topology-phase1.md: API Gateway labeled "Nginx/GraphQL"; routes labeled "REST/GraphQL"reference/specs/design/functional-scope.md: Mentions "GraphQL schemas" as a contract formattracker-target-architecture.md(TAD): Only defines REST + OpenAPI 3.0 endpoints; no GraphQLprd.md: "REST + OpenAPI 3.0" as API standard (Section 10 Backend Stack)
Impact: Architects and agents have conflicting signals. Is GraphQL in scope? If yes, the TAD API design is incomplete. If no, the C4 and functional scope documents contain scope creep. Severity: HIGH Recommendation: PO + Lead Architect to decide: Is GraphQL a first-class surface in Phase 1? Options:
- Option A: Remove GraphQL from C4 and functional-scope; REST-only for Phase 1
- Option B: Add GraphQL explicitly to PRD EPIC-001 and design a GraphQL schema management strategy in the TAD
- Recommended: Option A (keep Phase 1 simple; GraphQL can be added in Phase 2 via ADR) Requires ADR: YES — register decision in DECISIONS.md Can auto-correct: NO (architectural decision) Status: ✅ RESOLVED (2026-06-07) — Option A adopted: REST + OpenAPI 3.0 only in Phase 1, registered as T-009. GraphQL removed from C4, functional-scope, and data-design CHECK.
Finding: tracker-target-architecture.md (in reference/specs/design/) contains these references:
- [PRD — Evolith Tracker](./prd.md)
- [UX Concept](./ux-concept.md)These resolve to reference/specs/design/prd.md and reference/specs/design/ux-concept.md — which do NOT exist. The actual files are in .bmad-core/deliverables/.
Correct paths from TAD location:
- [PRD — Evolith Tracker](../../../.bmad-core/deliverables/prd.md)
- [UX Concept](../../../.bmad-core/deliverables/ux-concept.md)Severity: HIGH Can auto-correct: YES — corrected in this audit (see corrections section)
Finding: .harness/adr/0002-adoption-minimal-apis-vs-controllers.md documents a decision about .NET 8/9 Minimal APIs and "Native AOT compilation" — technology not used in Evolith Tracker (Node.js/NestJS/TypeScript stack).
Impact: Confuses agents and developers reading harness ADRs as applicable to this project.
Severity: MEDIUM
Recommendation: Add a note to ADR-0002 clarifying it is inherited from the Evolith Core .NET reference implementation and does NOT apply to the Node.js satellite. Alternatively, prefix it with INHERITED_FROM_CORE_DOTNET in its status.
Can auto-correct: YES — add scope note to the ADR
Finding: DECISIONS.md contains only 2 entries (T-001: Nx monorepo, T-002: Microfrontends). However, the TAD references multiple Evolith Core ADRs adopted without registration:
| ADR Referenced in TAD | Registration in DECISIONS.md |
|---|---|
| ADR-0002 (Clean Hexagonal Architecture) | MISSING |
| ADR-0003 (TypeScript strict) | MISSING |
| ADR-0043 (TypeORM as ORM) | MISSING |
| ADR-0044 (React frontend) | MISSING |
| ADR-0045 (Zustand + TanStack Query) | MISSING |
Impact: Governance traceability broken — cannot determine which upstream decisions have been formally adopted. Severity: HIGH Recommendation: Register all referenced Core ADRs in DECISIONS.md with "Adoptar" operation. Can auto-correct: YES — corrected in this audit (see corrections section)
- Domain primitives defined (Entity, AggregateRoot, ValueObject, DomainEvent, Result)
- Domain Layer Rule explicitly stated: "Zero imports from NestJS, ORM, PostgreSQL, or external SDKs"
- Small Aggregates pattern applied (Backlog references
orderedStoryIds: List<UUID>— not nested objects)
Verdict: CORRECT
- Command/Query separation properly modeled
- CommandBus infrastructure pattern correct
- Result error handling pattern without exceptions
- Command side triggers domain events; Query side is read-only
Verdict: CORRECT
- Port + Adapter separation documented
- No infrastructure in domain layer
- Each aggregate root has its own repository interface
Verdict: CORRECT
- In-memory DomainEventBus defined
- TransactionalOutbox correctly modeled (pattern is sound)
- OutboxProcessor code now uses TypeORM (INC-T-002 resolved)
- Transactionality now explicit: CommandBus wraps each command in a Unit of Work; outbox writes commit inside the same transaction (TAD §12.1)
- In-memory bus delivery caveat now documented (TAD §13.1): in-memory dispatch is best-effort; at-least-once delivery is guaranteed by the outbox; consumers must be idempotent
Verdict: CORRECT
- JWT + UMS Authorization Graph integration documented
- UmsSecurityAdapter interface defined
- Permission mapping table (UMS → Tracker) documented
- TrackerPermissionGuard pattern correct
- Dedicated security spec now exists (
tracker-security-spec.md): STRIDE threat model, AuthN/AuthZ rules, token lifecycle, rate limiting, secrets management, OWASP Top 10, security testing - 7 security decisions (SEC-D1..D7: token TTL, secret manager, rate limits, webhook HMAC, at-rest encryption, headers/CSP, egress allowlist) flagged as ⊕ PROPOSAL pending owner ratification
Verdict: CORRECT (security architecture documented; concrete operational values pending human decisions, correctly marked as proposals)
- Feature-based module structure
- TanStack Query for server state (correct)
- Zustand for client state (correct)
- Permission-driven UI components
- Route guards per permission
- Types generated from OpenAPI contracts
Verdict: CORRECT
- OpenTelemetry SDK integration documented
- Structured logging with PII-safe pattern
- CorrelationId interceptor defined
- Dedicated observability spec now exists (
tracker-observability-spec.md): three signals, 6 dashboards, alerting rules, SLOs, instrumentation standards, multi-tenant constraints - 5 ⊕ proposals (OB-D1..D5: stack choice, SLO targets, retention, runbooks, paging) pending DevOps ratification
Verdict: CORRECT (observability design documented; concrete tool/targets pending DevOps decisions, correctly marked as proposals)
- Schema-per-domain isolation ✓
- No foreign keys between schemas ✓
- UUID primary keys with
gen_random_uuid()✓ - RLS for tenant isolation ✓
- Optimistic concurrency via
xmin✓ - TIMESTAMPTZ for UTC ✓
- Blocking: Schema names are inconsistent across documents (INC-T-001)
Verdict: PARTIALLY_CORRECT
| Document | Impact | Severity |
|---|---|---|
✅ RESOLVED — tracker-test-strategy.md created |
— | |
✅ RESOLVED — tracker-security-spec.md created (7 ⊕ proposals pending owner sign-off) |
— | |
✅ RESOLVED — tracker-cicd-spec.md created (6 ⊕ proposals pending) |
— | |
| CI/CD Pipeline Specification | No automated pipeline definition | HIGH |
| OpenAPI Specification Files | Design phase output required before Construction | MEDIUM |
| Observability Dashboard Spec | Cannot configure Grafana/alerting | MEDIUM |
The following patterns in the TAD are correctly sized for Phase 1:
- In-memory event bus (correct — avoids premature broker dependency)
- Progressive Monolith (correct — no premature microservice extraction)
- UUID references instead of nested aggregates (correct — Small Aggregates pattern)
No overengineering detected. The architecture appropriately defers complexity.
Fixed in: tracker-target-architecture.md
./prd.md→../../../.bmad-core/deliverables/prd.md./ux-concept.md→../../../.bmad-core/deliverables/ux-concept.md
Fixed in: tracker-target-architecture.md
Replaced Prisma syntax with TypeORM equivalent.
Added T-003 through T-007 to DECISIONS.md for formally adopted Core ADRs.
Added clarification that ADR-0002 applies to .NET reference only.
Adopted tracker_<context> across C4 topology and functional-scope (Design/Discovery, EN/ES).
REST + OpenAPI 3.0 declared sole Phase 1 API surface. Removed GraphQL from C4, functional-scope, and the contract_type CHECK constraint in data-design.
Updated C4 frontend tier (Shell Host + 5 remotes), TAD §20 (Module Federation), and react-frontend-design §1 to reflect the active microfrontend decision (T-002/T-002), replacing the prior single-SPA description.
Generated by: Architect Audit Role (BMAD) · 2026-06-07