You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Guardrails: Added non-negotiable interface/contract boundary rules for cross-module integration
12
12
Status: Approved — modular architecture and contract-first parallel delivery are now constitutional requirements
13
+
Current Update (v1.12.2): Added mandatory spec-completion gate requiring database migrations to be applied and E2E tests to pass before a spec can be marked done.
13
14
Previous Updates:
14
15
- v1.11.0: Strengthened TDD mandate with a strict gated red-green-refactor workflow requiring explicit user confirmation of failing tests before implementation.
15
16
- v1.10.2: Codified a mandatory post-change verification command matrix so every change runs explicit checks before merge.
@@ -55,7 +56,7 @@ Domain logic isolated from infrastructure concerns via layered architecture alig
55
56
56
57
### II. Functional Programming (Pure & Impure Sandwich)
57
58
58
-
Core calculations and business logic implemented as pure functions: distance-to-distance conversions, expense-to-savings transformations, weather-to-recommendation mappings. Pure functions have no side effects—given the same input, always return the same output. Use immutable data structures. Impure edges (database reads/writes, external API calls, user input, system time) explicitly isolated at application boundaries. Handlers orchestrate pure logic within impure I/O boundaries. **F# discriminated unions and active patterns preferred for domain modeling** (domain layer uses F#); Railway Oriented Programming (Result<'T> type) for error handling; C# records used in API surface for interop.
59
+
Core calculations and business logic implemented as pure functions: distance-to-distance conversions, expense-to-savings transformations, weather-to-recommendation mappings. Pure functions have no side effects—given the same input, always return the same output. Use immutable data structures. Impure edges (database reads/writes, external API calls, user input, system time) explicitly isolated at application boundaries. Handlers orchestrate pure logic within impure I/O boundaries. **F# discriminated unions and active patterns preferred for domain modeling** (domain layer uses F#); Railway Oriented Programming (Result<'T> type) for error handling; C# records used in API surface for interop.**C# expected business/validation/conflict flows MUST use explicit Result-style return values and MUST NOT use exceptions for routine control flow. Exceptions are reserved for unexpected/exceptional failures only.**
59
60
60
61
**Rationale**: Pure functions are trivially testable, deterministic, and composable. Side effect isolation makes dataflow explicit and reduces debugging complexity. Immutable data structures preferred where practical. F# enforces immutability and pattern matching, reducing entire categories of bugs. Discriminated unions make invalid states unrepresentable.
61
62
@@ -76,6 +77,9 @@ Red-Green-Refactor cycle is **non-negotiable** and follows a strict, gate-contro
76
77
5.**Run After Each Change**: Tests are run after each meaningful implementation change to track incremental progress toward green.
77
78
6.**All Tests Pass**: Implementation is complete only when all tests pass. No merge occurs until the full test suite is green.
78
79
7.**Consider Refactoring**: Once tests are green, evaluate the implementation for clarity, duplication, and simplicity. Refactor while keeping tests green. Refactoring is optional but explicitly encouraged at this stage.
80
+
8.**Commit At Each TDD Gate**: Commits are mandatory at each TDD gate transition with clear gate intent in the message. Required checkpoints: (a) red baseline committed after failing tests are written and user confirms failures, (b) green implementation committed when approved tests pass, (c) refactor committed separately when refactoring is performed.
81
+
82
+
TDD commit messages must include gate and spec/task context (for example: "TDD-RED: spec-006 ride history edit conflict tests" or "TDD-GREEN: spec-006 make edit totals refresh pass").
79
83
80
84
Unit tests validate pure logic (target 85%+ coverage). Integration tests verify each vertical slice end-to-end. Contract tests ensure event schemas remain backwards compatible. Security tests validate OAuth isolation and data access. **Agent must suggest tests with rationale; user approval required before implementation. User must confirm test failures before implementation begins.**
81
85
@@ -141,6 +145,7 @@ System capabilities must be split into cohesive modules with explicit ownership
141
145
-**Framework**: .NET 10 Minimal API (latest stable)
142
146
-**Orchestration**: Microsoft Aspire (latest stable) for local and cloud development
143
147
-**Language (API Layer)**: C# (latest language features: records, pattern matching, async/await, follow .editorconfig for code formatting)
148
+
-**Language (API Layer)**: C# (latest language features: records, pattern matching, async/await, follow .editorconfig for code formatting); expected-flow outcomes MUST be represented with explicit Result objects rather than exception-driven control flow
144
149
-**Language (Domain Layer)**: F# (latest stable) for domain entities, events, value objects, services, and command handlers. Discriminated unions, active patterns, and Railway Oriented Programming pattern used for domain modeling and error handling.
145
150
-**NuGet Discipline**: All packages must be checked monthly for updates; security patches applied immediately; major versions reviewed for breaking changes before upgrade
146
151
-**Domain-Infrastructure Interop**: EF Core value converters (FSharpValueConverters) enable transparent mapping of F# discriminated unions to database columns
@@ -387,6 +392,8 @@ Tests suggested by agent must receive explicit user approval before implementati
387
392
12.**Local Deployment**: Slice deployed locally in containers via Aspire, tested manually with Playwright if E2E slice
388
393
13.**Azure Deployment**: Slice deployed to Azure Container Apps via GitHub Actions + azd
389
394
14.**User Acceptance**: User validates slice meets specification and data validation rules observed
395
+
15.**Phase Completion Commit**: Before starting the next phase, create a dedicated phase-completion commit that includes completed tasks and verification evidence for that phase
396
+
16.**Spec Completion Gate**: Before marking any specification as done, database migrations for that spec must be applied successfully to the target local runtime database and the spec's end-to-end (Playwright) tests must run green
390
397
391
398
### Compliance Audit Checklist
392
399
@@ -400,6 +407,10 @@ Tests suggested by agent must receive explicit user approval before implementati
400
407
-[ ] Module boundaries documented; cross-module integrations use approved interfaces/contracts only
401
408
-[ ] Contract compatibility tests executed for changed APIs/events (provider and consumer)
402
409
-[ ] Security issues recognized, explained, and remediated (or explicitly accepted by user)
410
+
-[ ] TDD gate commits created: red baseline commit, green commit, and separate refactor commit when applicable
411
+
-[ ] Phase completion commit created before moving to the next phase
412
+
-[ ] Database migrations for the spec are created and applied successfully to the runtime database used for validation
413
+
-[ ] Spec-level E2E (Playwright) suite executed and passing before spec marked complete
403
414
-[ ] All SAMPLE_/DEMO_ data removed from code before merge
-[ ] Validation rule consistency: if field required in React form, enforced in API DTOs and database constraints
@@ -432,6 +443,9 @@ Tests suggested by agent must receive explicit user approval before implementati
432
443
Breaking these guarantees causes architectural decay and technical debt accrual:
433
444
434
445
-**TDD cycle is strictly gated and non-negotiable** — implementation code must never be written before failing tests exist, have been run, and the user has reviewed and confirmed the failures. The sequence is always: plan tests → write tests → run and prove failure → get user confirmation → implement → run after each change → verify all pass → consider refactoring. Skipping or reordering any step is prohibited.
446
+
-**Commit gates are mandatory for TDD and phase transitions** — every TDD gate transition requires a commit (red, green, and refactor when performed), and every completed phase requires a dedicated phase-completion commit before proceeding.
447
+
-**Spec completion requires migration + E2E gates** — a spec cannot be marked done until its database migrations are applied to the runtime database and its Playwright E2E scenarios pass.
448
+
-**Expected-flow C# logic uses Result, not exceptions** — validation, not-found, conflict, and authorization business outcomes must be returned via typed Result objects (including error code/message metadata). Throwing exceptions for these expected outcomes is prohibited; exceptions are only for truly unexpected failures.
435
449
-**Cross-module work is contract-first and interface-bound** — teams must integrate through explicit interfaces and versioned contracts only; direct coupling to another module's internal implementation is prohibited.
436
450
-**No Entity Framework DbContext in domain layer** — domain must remain infrastructure-agnostic. If domain needs persistence logic, use repository pattern abstracting EF.
437
451
-**Secrets management by deployment context** — **Cloud**: all secrets in Azure Key Vault; **Local**: User Secrets or environment variables. No connection strings, API keys, or OAuth secrets in appsettings.json, code, or GitHub. Pre-commit hooks enforce this. **⚠️ This repository is public on GitHub**: any committed secret is immediately and permanently exposed to the internet; treat any accidental secret commit as an immediate security incident requiring credential rotation.
@@ -518,7 +532,7 @@ All SpecKit templates must reflect this constitution:
518
532
### Runtime Guidance
519
533
Development workflow guidance documented in [README.md](../../README.md) and .github/prompts/ directory. This constitution establishes governance; runtime prompts add context and tool references.
520
534
521
-
Always commit before continuing to a new phase.
535
+
Always commit at each TDD gate and before continuing to a new phase.
522
536
523
537
### Related Documents
524
538
-**[DECISIONS.md](./DECISIONS.md)**: Amendment history, version changelog, rationale for major decisions
@@ -528,5 +542,5 @@ Always commit before continuing to a new phase.
Copy file name to clipboardExpand all lines: specs/004-create-the-record-ride-mvp/plan.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,7 @@
5
5
6
6
## Summary
7
7
8
-
Implement an authenticated Record Ride vertical slice that lets riders submit required date/time and miles, optionally submit minutes and temperature, and persist each successful submission as an immutable `RideRecorded` event payload via the existing outbox event pipeline. Deliver a React page with smart defaults (`now` for date/time and last ride values for optional defaults), plus Minimal API command/query endpoints and persistence support aligned with the current architecture.
8
+
Implement an authenticated Record Ride vertical slice that lets riders submit required date/time and miles, optionally submit minutes and temperature, and persist each successful submission as an immutable `RideRecorded` event payload via the existing outbox event pipeline. Deliver a React page with smart defaults (`now` for date/time and last ride values for optional defaults), plus Minimal API command/query endpoints and persistence support aligned with the current architecture. Validation includes miles > 0 and <= 200.
9
9
10
10
## Technical Context
11
11
@@ -16,7 +16,7 @@ Implement an authenticated Record Ride vertical slice that lets riders submit re
16
16
**Target Platform**: Linux DevContainer local development, browser frontend, containerized local orchestration via Aspire
17
17
**Project Type**: Web application (React frontend + .NET Minimal API backend)
18
18
**Performance Goals**: API response under 500ms p95 for ride record/defaults endpoints; defaults query should be single-latest lookup per rider
19
-
**Constraints**: Must preserve exact submitted values; miles > 0 and optional rideMinutes > 0 when provided; maintain auth isolation and retry-friendly UX
19
+
**Constraints**: Must preserve exact submitted values; miles > 0 and <= 200 and optional rideMinutes > 0 when provided; maintain auth isolation and retry-friendly UX
20
20
**Scale/Scope**: MVP feature for authenticated riders, single-user local-first profile, many rides per rider over time
21
21
22
22
## Constitution Check
@@ -43,7 +43,7 @@ No constitutional violations identified; no complexity exceptions required.
43
43
|------|--------|-------|
44
44
| Architecture and boundaries preserved | PASS | Data model and contracts keep read/write concerns separated (`/api/rides` and `/api/rides/defaults`). |
45
45
| Event contract discipline | PASS | Dedicated `RideRecorded` JSON schema and API contract defined in feature contracts. |
46
-
| Validation depth | PASS | Validation rules documented in data model and surfaced in API/UX quickstart steps. |
46
+
| Validation depth | PASS | Validation rules documented in data model and surfaced in API/UX quickstart steps, including miles upper bound <= 200. |
47
47
| UX consistency/accessibility | PASS | Route is authenticated, field semantics explicit, and success/error feedback required. |
48
48
| Verification and testing discipline | PASS WITH ACTION | Execution commands documented; strict red-green sequence remains required in tasks phase. |
Copy file name to clipboardExpand all lines: specs/004-create-the-record-ride-mvp/spec.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -71,7 +71,7 @@ As a rider, I want to save a ride without duration or temperature when I do not
71
71
-**FR-006**: System MUST default optional ride minutes to the most recently saved ride minutes value for that rider when one exists.
72
72
-**FR-007**: System MUST default optional temperature to the most recently saved temperature value for that rider when one exists.
73
73
-**FR-008**: System MUST allow submission when optional ride minutes and optional temperature are blank.
74
-
-**FR-009**: System MUST validate that miles is greater than zero.
74
+
-**FR-009**: System MUST validate that miles is greater than zero and less than or equal to 200.
75
75
-**FR-010**: System MUST validate that optional ride minutes, when provided, is greater than zero.
76
76
-**FR-011**: System MUST persist each submitted ride to the database as a new ride event associated with the submitting rider.
77
77
-**FR-012**: System MUST preserve the exact submitted ride date/time and numeric values in persisted ride event data.
@@ -99,4 +99,4 @@ As a rider, I want to save a ride without duration or temperature when I do not
99
99
-**SC-003**: 100% of page loads default date/time to the current moment.
100
100
-**SC-004**: 100% of page loads for riders with prior data prefill miles from the rider's last saved ride.
101
101
-**SC-005**: 100% of successful submissions allow optional minutes and temperature to be omitted.
102
-
-**SC-006**: For invalid numeric input (non-positive miles or non-positive optional minutes), 100% of submissions are blocked with a visible validation message.
102
+
-**SC-006**: For invalid numeric input (non-positive miles, miles above 200, or non-positive optional minutes), 100% of submissions are blocked with a visible validation message.
0 commit comments