# INVEETAIRE
## SPRINT 1 PLANNING DOCUMENT

| Field | Value |
|-------|-------|
| Document Type | Sprint Planning |
| Sprint | Sprint 1 — Core Utilities |
| Version | 1.0 |
| Status | Ready for Implementation |
| Prerequisite | Sprint 0 ✅ COMPLETE (commit e961697) |
| Framework | Frozen — immutable during Sprint 1 |
| Based On | MIB v1.1 · DBP v1.1 · AI.md v1.1 · ADR v1.0 · SPRINT0_ARCHITECTURE_REVIEW.md |

---

## 1. Sprint Objective

Sprint 1 delivers the **Core Utilities** layer: CSRF form protection, a complete public-facing asset build pipeline, and foundational shared services that all module implementations will depend on in Sprints 2–15.

Sprint 1 does not implement Authentication or any business domain feature. It ensures that every subsequent sprint has the middleware infrastructure, validated CSRF pipeline, and tested CSS/JS foundation it needs to build safely.

**Sprint 1 completes when**: All Sprint 1 tasks pass their acceptance criteria, all tests pass, and `app/middleware/` contains production-ready `CsrfMiddleware.php` and `MiddlewareInterface.php`, with no kernel modifications.

---

## 2. Sprint Scope

Sprint 1 is the **Core Utilities** sprint. It is strictly scoped to:

1. **MiddlewareInterface** — formal contract for all future middleware classes
2. **CsrfMiddleware** — wires `Csrf::validate()` into the POST request pipeline
3. **Asset build pipeline** — compiled TailwindCSS and Alpine.js; replaces CDN approach
4. **Shared utility services** — any cross-module utility services identified as Sprint 1 prerequisites

**Not in scope for Sprint 1:**
- Authentication (Sprint 2)
- Authorization middleware (Sprint 2)
- Any business domain module
- Database schema changes
- Workspace or user management

---

## 3. Sprint Deliverables

| Deliverable | Type | File(s) |
|-------------|------|---------|
| Middleware interface contract | New file | `app/core/MiddlewareInterface.php` |
| CSRF protection middleware | New file | `app/middleware/CsrfMiddleware.php` |
| Compiled CSS build | New/Updated | `public/assets/css/app.css` |
| Compiled JS build | New/Updated | `public/assets/js/app.js` |
| Layout CDN replacement | Modified | `app/views/layouts/*.php` — replace CDN `<script>` with compiled asset links |
| Sprint 1 implementation memories | New files | `.ai/memory/` — per-task memory files |

> **Note on route files**: Route files created in INIT-007 are skeletons. Sprint 1 does not add routes — authentication routes are a Sprint 2 concern. Route files are only modified when their implementing sprint begins.

---

## 4. Dependency Review

### 4.1 Why Sprint 1 Needs No Kernel Modification

Every Sprint 1 deliverable uses existing infrastructure via documented extension points:

| Sprint 1 Need | Sprint 0 Infrastructure Already Available |
|--------------|------------------------------------------|
| `CsrfMiddleware` needs CSRF validation | `Csrf::validate(Request)` — implemented in INIT-010 |
| `CsrfMiddleware` needs token access | `Csrf::getToken()` — implemented in INIT-010 |
| `CsrfMiddleware` needs session read | `Session::get()` — implemented in INIT-010 |
| `CsrfMiddleware` must fit pipeline | `MiddlewarePipeline::wrap()` — implemented in INIT-009 |
| `CsrfMiddleware` needs error response | `ErrorHandler::renderForbidden()` — implemented in INIT-006 |
| `MiddlewareInterface` needs Request type | `App\Core\Request` — implemented in INIT-007 |
| CSS compilation replaces CDN `<script>` | `public/assets/css/app.css` placeholder — created in INIT-001 |
| JS compilation replaces inline config | `public/assets/js/app.js` placeholder — created in INIT-001 |

### 4.2 Extension Points Used

Sprint 1 extends the framework at the two documented extension points:

1. **New middleware** — a class implementing `handle(Request, callable): void` is automatically recognized by `MiddlewarePipeline::wrap()` without any pipeline changes.
2. **New asset files** — the layout files reference `/assets/css/app.css` and `/assets/js/app.js`; populating these files requires no layout change.

**No kernel file requires modification in Sprint 1.**

---

## 5. Implementation Order

Dependency order governs sequence — not task identifiers.

```
CORE-001 (MiddlewareInterface)
    │
    └── CORE-002 (CsrfMiddleware)
            │
            └── CORE-003 (Asset Build Pipeline)
                    │
                    └── CORE-004 (Layout CDN Replacement)
```

### CORE-001 — MiddlewareInterface

**Why first**: `CsrfMiddleware` must implement the interface. The interface must exist before any concrete middleware is written.

**Delivers**: `app/core/MiddlewareInterface.php`

**Contract**:
```
interface MiddlewareInterface
{
    public function handle(Request $request, callable $next): void;
}
```

`MiddlewarePipeline::wrap()` should be updated to add an `instanceof MiddlewareInterface` check alongside the existing `method_exists()` check. This is the only permitted modification to an existing file in Sprint 1 — and it is an additive check, not a behavioral change.

> **Note on kernel modification rule**: Adding an `instanceof` guard to `MiddlewarePipeline::wrap()` is strictly additive and does not alter middleware execution logic. It is the documented resolution of TD-001 from the Architecture Review. All other kernel files remain frozen.

---

### CORE-002 — CsrfMiddleware

**Why second**: Requires `MiddlewareInterface` (CORE-001) and `Csrf::validate()` (INIT-010, available).

**Delivers**: `app/middleware/CsrfMiddleware.php`

**Responsibilities**:
- Implements `MiddlewareInterface`
- On POST: calls `Csrf::validate($request)`
- On failure: calls `ErrorHandler::renderForbidden()` — no raw output
- On success: calls `$next($request)` to continue the pipeline
- Non-POST requests pass through unconditionally
- No session, database, or authentication dependency

**Not in scope**: Route-level CSRF bypasses, AJAX token headers. These are deferred to the sprints that need them.

---

### CORE-003 — Asset Build Pipeline

**Why third**: CSS and JS must be compiled before layouts reference them. Can proceed independently of CORE-002 if parallel work is available, but logically follows CORE-001/002 completion as a sprint unit.

**Delivers**:
- `public/assets/css/app.css` — compiled Tailwind CSS
- `public/assets/js/app.js` — Alpine.js + application utilities

**Tailwind compilation**: Run Tailwind CLI against the four layout files and component files to generate a purged, production-ready CSS file.

**Alpine.js**: Copy the current Alpine.js CDN version to a local file or include it in the build step.

---

### CORE-004 — Layout CDN Replacement

**Why fourth**: Depends on CORE-003 assets being ready.

**Modifies**:
- `app/views/layouts/couple.php`
- `app/views/layouts/admin.php`
- `app/views/layouts/crew.php`
- `app/views/layouts/public.php`

**Change**: Replace the inline `<script src="https://cdn.tailwindcss.com">` and inline `tailwind.config` with:

```html
<link rel="stylesheet" href="/assets/css/app.css">
<script src="/assets/js/app.js" defer></script>
```

Eliminates the external CDN dependency. Resolves TD-004 from the Architecture Review.

---

## 6. Expected Repository Changes

### New Folders
None. All required directories exist from Sprint 0 (INIT-001).

### New Files

| File | Created By |
|------|-----------|
| `app/core/MiddlewareInterface.php` | CORE-001 |
| `app/middleware/CsrfMiddleware.php` | CORE-002 |
| `app/middleware/.gitkeep` | Remove — replaced by actual file |

### Existing Files Modified

| File | Modified By | Nature of Change |
|------|------------|-----------------|
| `app/core/MiddlewarePipeline.php` | CORE-001 | Add `instanceof MiddlewareInterface` check (additive only) |
| `app/views/layouts/couple.php` | CORE-004 | Replace CDN `<script>` with compiled asset `<link>` |
| `app/views/layouts/admin.php` | CORE-004 | Replace CDN `<script>` with compiled asset `<link>` |
| `app/views/layouts/crew.php` | CORE-004 | Replace CDN `<script>` with compiled asset `<link>` |
| `app/views/layouts/public.php` | CORE-004 | Replace CDN `<script>` with compiled asset `<link>` |
| `public/assets/css/app.css` | CORE-003 | Replace placeholder with compiled Tailwind output |
| `public/assets/js/app.js` | CORE-003 | Replace placeholder with Alpine.js + utilities |

### Files That Must NOT Be Modified

| File | Reason |
|------|--------|
| `app/core/Bootstrap.php` | Kernel — frozen |
| `app/core/Router.php` | Kernel — frozen |
| `app/core/Session.php` | Kernel — frozen |
| `app/core/Csrf.php` | Kernel — frozen |
| `app/core/Database.php` | Kernel — frozen |
| `app/core/BaseController.php` | Kernel — frozen |
| `app/core/BaseModel.php` | Kernel — frozen |
| `app/core/BaseService.php` | Kernel — frozen |
| `app/core/ErrorHandler.php` | Kernel — frozen |
| `app/core/Logger.php` | Kernel — frozen |
| `app/core/Application.php` | Kernel — frozen |
| `app/core/FlashMessage.php` | Kernel — frozen |
| `app/core/Request.php` | Kernel — frozen |
| `routes/*.php` | Not yet wired — Sprint 2+ |
| All config files | No Sprint 1 config changes required |

---

## 7. Architectural Constraints

The following rules inherited from Sprint 0 govern all Sprint 1 implementation:

### Kernel Immutability
The Sprint 0 kernel is frozen. No file in `app/core/` may be modified except `MiddlewarePipeline.php` for the additive `instanceof` check documented in CORE-001. Any other kernel change requires a new Design Revision Pack and user approval before implementation.

### Extend, Don't Alter
New functionality is added by creating new files in designated locations. Existing files are modified only when documented and approved.

### PSR-4 Only
The `App\` namespace maps to `app/`. Class `App\Middleware\CsrfMiddleware` → `app/middleware/CsrfMiddleware.php`. No Composer autoloader. No manual require chains for namespaced classes.

### Native PHP 7.4
No PHP 8.x syntax. No third-party packages. No frameworks. No Composer dependencies in the application layer.

### Parameterized PDO Only
No string-interpolated SQL. All queries through `BaseModel::query()`. (Sprint 1 has no database queries — this constraint becomes active in Sprint 2.)

### No Business Logic in Controllers
Controllers receive input, call a service, return a response. Sprint 1 middleware is not a controller — but the same principle applies: middleware must be thin and single-purpose.

### Middleware Remains Thin
`CsrfMiddleware` must do exactly one thing: validate the CSRF token on POST. It must not touch authentication, sessions beyond token comparison, or produce any HTML output directly.

### Services Orchestrate, Models Access Data
Sprint 1 does not add services or models. This constraint is recorded here for Sprint 2 reference.

### Output Escaping
Any new view output in Sprint 1 must use `escape_html()`. The rule is absolute — no raw `echo $variable` anywhere.

### No Stub Files
`app/middleware/` must not contain stub files for future middleware. Only `CsrfMiddleware.php` (Sprint 1) is created. `AuthMiddleware.php`, `RoleMiddleware.php`, and others are created in their implementing sprints.

---

## 8. AI Implementation Rules

The following operational rules govern AI agent behavior during Sprint 1 implementation:

### Before Any Code Is Written

1. **Read mandatory references**: AI.md v1.1, PROJECT.md, WORKFLOW.md, IMPLEMENTATION_ROADMAP.md, MIB v1.1, DBP v1.1, ADR, TCS, DRP v2.0, this Sprint 1 Planning document.
2. **Review previous Sprint 0 implementation**: Read all `.ai/memory/` files. Read the Sprint 0 Architecture Review. Understand the existing kernel before touching anything.
3. **Review the current repository state**: Verify all Sprint 0 files are present. Verify `app/middleware/` contains only `.gitkeep`.

### During Implementation

4. **One task per session**: Implement exactly one numbered task (CORE-001, CORE-002, etc.) per AI session. Do not partially implement a task. Do not start the next task without user approval.
5. **Files Expected governs scope**: Create only the files listed under the task's "Files Expected". Do not create additional files unless explicitly approved.
6. **Stop on documentation conflict**: If any lower-level document conflicts with a higher-level document, stop immediately, report the conflict, and wait for user approval before proceeding. Do not resolve conflicts autonomously.
7. **Stop on undocumented prerequisite**: If a prerequisite file or class is absent that was expected to exist, stop, report, and wait. Do not create undocumented files to unblock yourself.
8. **Do not execute Git commands**: Stage, commit, and push operations are performed by the user. AI agents produce code and implementation reports only.

### After Implementation

9. **Produce an implementation report**: After completing each task, produce a markdown implementation report covering: files created, files modified, acceptance criteria verification, deviations (if any), and open questions.
10. **Wait for user approval**: Do not proceed to the next task without explicit user approval. The user reviews the implementation report and the produced files before authorizing continuation.

---

## 9. Sprint Success Criteria

Sprint 1 is successful when all of the following are true:

| Criterion | Verification Method |
|-----------|-------------------|
| `MiddlewareInterface.php` exists and declares `handle(Request, callable): void` | File inspection |
| `CsrfMiddleware.php` implements `MiddlewareInterface` | File inspection |
| POST request with missing CSRF token → 403 response | Manual test |
| POST request with valid CSRF token → proceeds to controller | Manual test |
| GET requests are not blocked by CSRF middleware | Manual test |
| `MiddlewarePipeline::wrap()` includes `instanceof MiddlewareInterface` check | File inspection |
| `public/assets/css/app.css` is non-empty compiled Tailwind output | File inspection |
| `public/assets/js/app.js` is non-empty Alpine.js bundle | File inspection |
| All four layouts reference local CSS/JS — no CDN `<script>` tags | File inspection |
| No kernel file modified except the permitted `MiddlewarePipeline.php` addition | Git diff |
| No stub middleware files created for future sprints | Directory listing |
| All Sprint 0 kernel tests still pass | CLI test run |
| Implementation memory files written for each completed task | `.ai/memory/` inspection |

---

## 10. Sprint Exit Criteria

Sprint 1 may be declared complete when:

1. All Sprint 1 Success Criteria above are verified ✅
2. TD-001 (MiddlewareInterface Missing) is resolved ✅
3. TD-004 (TailwindCSS CDN in Production Layouts) is resolved ✅
4. No new technical debt is introduced without documentation ✅
5. Implementation memory files are written and committed for each task ✅
6. An implementation report has been produced and reviewed for each task ✅
7. The user has explicitly approved Sprint 1 completion ✅

**Sprint 2 (Authentication) may only begin after Sprint 1 Exit Criteria are met.**

---

## 11. Known Risks

The following risks are relevant to Sprint 1. All others from the Architecture Review are deferred.

### R-S1-01 — CSRF Middleware Timing (Medium)

**Risk**: `CsrfMiddleware` is wired to all POST routes globally. If a future sprint needs a CSRF-exempt POST endpoint (e.g., a webhook receiver), the per-route middleware registration model must accommodate it.

**Probability**: Low for Sprint 1 itself. Medium for Sprints 3–5 when webhooks may be introduced.

**Impact**: Medium — incorrect blanket enforcement could block legitimate POST requests in later sprints.

**Mitigation**: Document the per-route middleware registration pattern clearly in CORE-002 implementation memory. Routes that need CSRF exemption simply do not include `CsrfMiddleware` in their middleware list.

**Target**: Documented in CORE-002 memory before Sprint 2 begins.

---

### R-S1-02 — Asset Pipeline Tooling (Low)

**Risk**: Tailwind CLI compilation requires Node.js tooling. On XAMPP (Windows), this may not be pre-installed.

**Probability**: Low — Node.js is widely available. High on bare-minimum XAMPP installs.

**Impact**: Low — the CDN fallback remains functional. Asset compilation is a quality improvement, not a functional blocker.

**Mitigation**: Document the build step clearly. If Node.js is unavailable, the CDN approach from Sprint 0 continues to function while the environment is prepared.

**Target**: CORE-003 implementation prompt includes Node.js prerequisite check.

---

### R-S1-03 — MiddlewarePipeline Modification Risk (Low)

**Risk**: Adding an `instanceof MiddlewareInterface` check to `MiddlewarePipeline::wrap()` is the only permitted kernel modification in Sprint 1. If the implementation is incorrect, it could affect the pipeline for all future middleware.

**Probability**: Low — the change is minimal (one additional condition).

**Impact**: High if incorrect — could break middleware dispatch for all subsequent sprints.

**Mitigation**: The change must be reviewed against the existing `method_exists()` check. The `instanceof` check is ADDITIVE — it logs a warning but does not short-circuit middleware execution, so existing behavior is preserved. This must be verified before proceeding to CORE-002.

**Target**: CORE-001 acceptance criteria explicitly verify that existing (empty) pipeline behavior is unchanged.

---

### R-S1-04 — MIB Epic 1 in .docx Format (Low)

**Risk**: Sprint 1 tasks (CORE-001–004) are defined in the v1.0 `.docx` MIB binary, not the Markdown v1.1. An AI agent cannot natively parse `.docx` without extraction tooling, creating potential for misreading task requirements.

**Probability**: Medium — `.docx` requires additional extraction step for each session.

**Impact**: Low — this Sprint Planning document captures all Sprint 1 task definitions explicitly. AI agents may reference this document as the authoritative Sprint 1 source.

**Mitigation**: This Sprint 1 Planning document (`SPRINT1_PLANNING.md`) is the operative planning reference. The `.docx` MIB remains the parent authority but this document captures all Sprint 1 specifics.

**Target**: Resolved by this document.

---

## 12. Recommendations

The following observations are offered for the team's consideration. None are implementation requirements.

**OBS-01 — Produce MIB Sprint 1 Markdown before CORE-001 begins.**
Converting the MIB Epic 1 section from `.docx` to Markdown before implementation begins eliminates R-S1-04 and ensures AI sessions have direct, readable access to all task definitions. This is consistent with the pattern established for Epic 0.

**OBS-02 — Add `$layout` enforcement warning to BaseController.**
TD-001 resolution (`MiddlewareInterface`) is in scope for Sprint 1. Additionally, adding a `Logger::warning()` call in `BaseController::render()` when `$layout === 'app'` and no `app.php` layout exists would surface accidental missing-layout bugs at development time without modifying the behavior. This is the R-04 recommendation from the Architecture Review.

**OBS-03 — Write the Sprint 1 Execution Plan before CORE-001 begins.**
The Sprint 0 Execution Plan was a valuable reference throughout INIT implementation. An equivalent Sprint 1 Execution Plan (analogous to the `.ai/` prompt files used in Sprint 0) would ensure consistent task prompting and reduce per-session overhead.

**OBS-04 — Verify `app/middleware/.gitkeep` removal is intentional.**
When `CsrfMiddleware.php` is created in `app/middleware/`, the `.gitkeep` file becomes redundant. The directory will no longer be empty. Verify that the `.gitkeep` deletion is included in the CORE-002 implementation task.

---

## Appendix A: Sprint 1 Task Summary

| Task | Name | Size | Depends On | Files Produced |
|------|------|------|-----------|----------------|
| CORE-001 | MiddlewareInterface | XS | Sprint 0 complete | `app/core/MiddlewareInterface.php` |
| CORE-002 | CsrfMiddleware | S | CORE-001 | `app/middleware/CsrfMiddleware.php` |
| CORE-003 | Asset Build Pipeline | M | Sprint 0 layout files | `public/assets/css/app.css`, `public/assets/js/app.js` |
| CORE-004 | Layout CDN Replacement | XS | CORE-003 | 4 × `app/views/layouts/*.php` (modified) |

---

## Appendix B: Sprint 1 Architecture Extension Map

```
Sprint 0 Kernel (frozen)
    │
    ├── MiddlewareInterface (CORE-001)  ← new contract
    │       │
    │       └── CsrfMiddleware (CORE-002)  ← implements interface
    │               │
    │               └── wires into existing MiddlewarePipeline (unchanged)
    │
    ├── public/assets/css/app.css (CORE-003)  ← compiled from layout classes
    ├── public/assets/js/app.js  (CORE-003)  ← Alpine.js + utilities
    │
    └── layouts/*.php (CORE-004)  ← replace CDN with local assets
```

No new module directories. No new routes. No database changes. Sprint 1 strengthens infrastructure — it does not add features.

---

*Document produced: 2026-07-01*  
*Based on: MIB v1.1 · DBP v1.1 · AI.md v1.1 · ADR v1.0 · SPRINT0_ARCHITECTURE_REVIEW.md*  
*Sprint 0 commit: e961697*  
*Status: Ready for Sprint 1 implementation*
