# Headroom - Complete Decision Log & Conversation Archive

**Version:** 1.0  
**Date:** February 17, 2026  
**Participants:** Santhosh J (Project Owner), AI Assistant (Design Partner)  
**Purpose:** Comprehensive record of all discussions, decisions, considerations, and deferrals  

---

## Table of Contents

1. [Project Genesis](#project-genesis)
2. [Requirements Discovery](#requirements-discovery)
3. [Technical Stack Decisions](#technical-stack-decisions)
4. [Architecture Decisions](#architecture-decisions)
5. [Quality & Testing Decisions](#quality--testing-decisions)
6. [Deferred Features](#deferred-features)
7. [Rejected Options](#rejected-options)
8. [Open Questions](#open-questions)
9. [Timeline](#timeline)

---

## Project Genesis

### The Problem

**Context:**
- Managing team of 10-15 developers
- Handling 10-12 concurrent projects in various phases
- Currently using spreadsheets → "a nightmare"

**Pain Points Identified:**
1. **Capacity calculation chaos**: Manual calculations across holidays, PTO, weekends
2. **No validation**: Easy to over-allocate people or projects
3. **Visibility gap**: Hard to answer "Who has headroom for new work?"
4. **Billing errors**:
   - Over-allocation → Overcharge clients → Escalations
   - Under-allocation → Undercharge → Revenue loss
5. **No audit trail**: Changes are invisible
6. **Actual vs Planned tracking**: Difficult to compare what was planned vs what actually happened

### The Vision

**Product Name:** Headroom
- **Why this name?** It's the word managers actually say ("do we have headroom for this?"), immediately signals capacity planning, and captures the over/under allocation anxiety central to the tool.
- **Close runner-up:** Margin (protecting margin through accurate forecasting)

**Core Value:**
> Know exactly who has headroom for new work, prevent billing errors, forecast revenue, track planned vs actual hours.

### Personas

Four distinct user types identified:

| Persona | Primary Need |
|---------|--------------|
| **Superuser** | System setup, configuration, admin controls |
| **Managers** | Resource planning, allocation, team oversight |
| **Developers** | View allocations, log hours, understand workload |
| **Top Brass** | Executive reports, forecasts, budget visibility |

---

## Requirements Discovery

### The Monthly Cycle

**Key Insight:** The workflow is organized around monthly capacity planning cycles, not continuous allocation.

```
Monthly Cycle:
1. Capacity Planning → Who's available, how much?
2. Project Setup → What work needs to be done?
3. Resource Allocation → Who does what?
4. Actuals Tracking → What actually happened?
```

### Capacity Planning Requirements

**Inputs:**
- Team member list (name, role, hourly rate)
- Calendar data (holidays, weekends)
- Individual PTO requests
- Daily availability: **0** (unavailable), **0.5** (half day), **1.0** (full day)

**Critical Clarification:**
- Initial assumption: "10 hrs for Dev" meant role-based allocation
- **Actual requirement:** Person-specific allocation ("10 hrs for Santhosh")
- Availability is per-person, per-day, not role-based

**Outputs Needed:**
1. Individual capacity (person-days per month)
2. Team capacity summary (total available person-days)
3. Possible revenue (if fully utilized)

### Project Management Requirements

**Project Lifecycle:**

```
NA/Support → Initial → Gathering Estimates → Estimate Pending Approval
                ↓
        Estimate Rework ←───────┘
                ↓
        Estimate Approved → Funded → Scheduled → In-Progress
                ↓
        Ready for Prod → Done
                ↓
        [Optional: On-Hold, Cancelled]
```

**Key Attributes:**
- **Approved Estimate**: Total billable hours approved by client
- **Forecasted Effort**: How those hours split across months
- **Project Type**: Project (billable) vs Support (ongoing ops)

**Validation Requirement:**
- **Over-forecast**: Allocated hours > Approved estimate → RED FLAG (will overcharge)
- **Under-forecast**: Allocated hours < Approved estimate → YELLOW FLAG (will undercharge)
- **Clarification:** "Under-forecast is NOT OK. This money is my salary! Always try to be 100%."

### Resource Allocation Requirements

**The "Matrix" Concept:**

```
For month M:
┌────────────────────────────────────────┐
│ Project  │ Dev A │ Dev B │ Dev C │ Ext │
├──────────┼───────┼───────┼───────┼─────┤
│ Proj X   │  40h  │  20h  │   0   │ 10h │
│ Proj Y   │  20h  │  40h  │  30h  │  0  │
└────────────────────────────────────────┘
```

**"Untracked Resource" Requirement:**
- Purpose: Accommodate hours for external team members (e.g., DevOps from another team)
- Billing: NOT tracked for revenue (like a joker in a deck of cards)
- Use case: "We might bill another team, but not track their specific person"

**Validation Rules:**
- Sum of project allocations should equal approved estimate (tolerance: ±5%)
- Cannot allocate more than person's monthly capacity (warning, not hard block)
- Visual indicators: GREEN (100%), YELLOW (<100%), RED (>100%)

### Actuals Tracking Requirements

**Data Entry:**
- **Frequency**: Monthly aggregate, but can be updated incrementally (weekly)
- **Method**: Manual entry (no time-tracking tool integration for MVP)

**Calculations:**
- **Running utilization**: (Allocated hours YTD) / (Capacity YTD) × 100%
- **Overall utilization**: (Allocated hours this month) / (Capacity this month) × 100%

**Display Requirement:**
- Show utilization % alongside capacity view

### Reporting Requirements

**Core Reports:**
1. **Forecast Summary** (multi-period)
2. **Utilization Summary**
3. **Cost Summary**

**Critical Requirement:**
> All reports must be highly customizable with filters (team, person, project, status, date range, type)

**Additional Requirements:**
- Master data / taxonomy for configurable items (roles, statuses, types)
- Support for multi-tenancy (deferred to post-MVP)

---

## Technical Stack Decisions

### Backend: Why Laravel?

**Question Raised:** "I chose Laravel because of my PHP background. Debate me if that is not a good choice."

**Consideration:**
- Alternative: SvelteKit full-stack (single framework)
- Alternative: Next.js + Node.js

**Decision:** Laravel
- **Rationale**: 
  - You have PHP background (lower learning curve)
  - Laravel is mature, robust for API development
  - Rich ecosystem (Scribe for API docs, Pest for testing, Pint for linting)
  - PostgreSQL support is excellent
  - Redis integration is first-class

**No pushback from AI:** Laravel is a solid choice for this use case.

### Frontend: The Great Debate

**Initial Question:** "May be Laravel + Svelte? Or Sveltekit itself?"

**Options Presented:**
1. Laravel + Blade Templates (rejected: less interactive)
2. Laravel + Vue.js (recommended by AI: stay in Laravel ecosystem)
3. **Laravel API + SvelteKit (separate)** ← CHOSEN
4. Laravel API + React (rejected: more learning curve)

**Decision:** Laravel API + SvelteKit (separate projects)
- **Your choice:** "Sveltekit it is!"
- **AI concern:** "Adds deployment complexity for MVP"
- **Your response:** "I will choose this."
- **Outcome:** Two separate containers, clean separation

**Why SvelteKit?**
- Modern, reactive
- Great for data-heavy dashboards
- Smaller bundle sizes than React/Vue
- You're willing to learn it

### Database: PostgreSQL from Day 1

**Question:** "SQLite for local, PostgreSQL for production?"

**Decision:** PostgreSQL from the start
- **Rationale**: 
  - Avoid migration pain later
  - Production-grade features (JSON operators, full-text search)
  - Better for reporting queries
  - Volume-mounted in Docker (portability maintained)

### Caching: Redis from Day 1

**Initial Recommendation:** "Start without caching, add in Phase 2 if slow"

**Your Response:** "Query caching and Response caching on Redis from Day 1. No need to sweat on refactoring it everywhere."

**Decision:** Redis caching from day 1
- **Rationale**: Prevents technical debt
- **Scope**: Query caching + Response caching
- **Implementation**: Laravel cache facade, automatic invalidation

### Authentication: JWT

**Question:** "Session-based or Token-based (JWT)?"

**AI Recommendation:** "Session-based is easier for same-origin setup"

**Your Choice:** "I will go with JWT."

**Rationale:**
- Token-based authentication
- Suitable for SPA frontend
- Easier to add mobile app later (if needed)

### UI Component Library

**Options Presented:**
- Shadcn/ui (headless, customizable)
- **DaisyUI** (Tailwind-based, fast) ← CHOSEN
- Svelte Material UI (full-featured)
- Build custom with Tailwind

**Decision:** DaisyUI
- **Rationale**: Faster to build dashboards, opinionated but fast
- **Your response:** "Daisy it is."

### Charts & Visualization

**Options Presented:**
- **Recharts** ← CHOSEN (AI recommendation)
- Chart.js
- Plotly
- Apache ECharts

**Decision:** Recharts
- **Rationale**: Good balance of power and simplicity
- **Your response:** "Agreed"

### Tables & Data Grid

**Options Presented:**
- **TanStack Table (React Table)** ← CHOSEN
- Svelte DataTable
- Build custom

**Decision:** TanStack Table
- **AI note:** "I am not familiar with this, but I will go with your recommendation."
- **Rationale**: Industry standard, powerful filtering/sorting, works with Svelte

### Forms & Validation

**Options Presented:**
- SvelteKit Form Actions + Superforms
- Direct API calls

**Additional Question:** "How about something like Superform or Zod?"

**Decision:** Superforms + Zod + SvelteKit Form Actions
- **Rationale**: 
  - Type-safe validation (Zod)
  - Form state management (Superforms)
  - Server-side handling (SvelteKit native)
  - Single source of truth for validation

### API Documentation

**Question Raised:** "How about SwaggerUI documentation for APIs?"

**Decision:** Laravel Scribe (auto-generates SwaggerUI)
- **Implementation**: `composer require knuckleswtf/scribe`
- **Output**: `/api/documentation` endpoint with OpenAPI spec
- **Lift**: ~1 hour setup
- **Inclusion**: From day 1

### Testing Stack

**Backend:**
- PHPUnit (unit tests)
- Pest (feature tests)

**Frontend:**
- Vitest (unit tests)
- Playwright (E2E tests)

**Decision:** Include all from day 1

### Version Strategy

**Question:** Which versions to use?

**Decision:** Use latest versions across the stack
- **Laravel 12** (latest major version)
- **PHP 8.4** (compatible with Laravel 12)
- **All other dependencies:** Use `:latest` tags (PostgreSQL, Redis, Node, npm packages)

**Rationale:** 
- Stay current with latest features and security patches
- Avoid version lock-in from the start
- Docker `:latest` tags ensure fresh installs get newest versions

---

## Architecture Decisions

### Containerization

**Requirement:** "From get go, everything must be containerised."

**Additional Constraint:** "Do not add any proxy manager (NPM, Caddy, or Traefik). My environment already runs an NPM."

**Decision:** Docker Compose with 4 containers
1. **Frontend**: SvelteKit (port 5173)
2. **Backend**: Laravel (port 3000)
3. **Database**: PostgreSQL (port 5432)
4. **Cache**: Redis (port 6379)

**Reverse Proxy:**
- Use existing Nginx Proxy Manager
- NPM routes `/api/*` → Laravel
- NPM routes `/*` → SvelteKit

### Multi-Tenancy

**Question:** "Should we build multi-tenant from day 1?"

**AI Recommendation:** "Start single-tenant. Add tenant_id column when needed."

**Your Response:** "AGREED"

**Rationale:** Reduces complexity, easy to add later

### Environment Configuration

**Question:** ".env files or Docker secrets?"

**AI Recommendation:** ".env files for local, Docker secrets in prod"

**Your Response:** ".env everywhere"

**Decision:** .env files in all environments
- Simpler configuration management
- Consistent across local/prod

### Development Environment

**Question:** "Docker Compose for local dev, or native setup?"

**AI Recommendation:** "Docker Compose from the start. Ensures prod parity."

**Your Response:** "100% agree. If possible, we should have at least the local dev avoid building after every change (may be code mounted)"

**Decision:** Docker Compose with code-mounted volumes
- Hot reload for both frontend and backend
- Avoid rebuilding containers on every change
- Volume mounts: `./frontend:/app`, `./backend:/var/www`

### Real-Time Updates

**Question:** "Do you need live updates (WebSockets), or is polling OK?"

**AI Recommendation:** "Start with polling. Add WebSockets if needed."

**Your Response:** "I dont think we need to sweat on it. Go with a basic implementation. Polling is good enough."

**Decision:** Polling (defer WebSockets to Phase 2)

### State Management (Frontend)

**Question:** "Svelte stores for UI state, or always fetch from API?"

**AI Recommendation:** "Use Svelte stores for UI state (filters, modals), API queries for data."

**Your Response:** "Agreed."

**Decision:** Minimal Svelte stores (UI state only)

### Report Exports

**Question:** "Will users need PDF/CSV exports?"

**AI Recommendation:** "Start with on-screen reports, add exports in phase 2."

**Your Initial Response:** "Good to have at this time."

**AI Clarification:** "Should exports be in MVP scope, or phase 2?"

**Final Decision:** Phase 2
- **Rationale**: Keeps MVP scope tight, adds 4 hours of work
- Interactive dashboard is primary value

### Caching Strategy

**Question Raised by You:** "Should we talk about a caching layer?"

**Options Discussed:**
1. Database Query Caching
2. API Response Caching
3. Full-page caching

**AI Recommendation:** "Start without caching, add Redis in Phase 2 if slow"

**Your Response:** "Query caching and Response caching on Redis from Day 1. No need to sweat on refactoring it everywhere."

**Decision:** Redis caching from day 1
- Query caching (expensive calculations)
- Response caching (GET endpoints)
- Automatic cache invalidation on mutations
- TTL: 1 hour (allocations), 15 min (reports), 24 hours (master data)

---

## Quality & Testing Decisions

### Project-Level Standing Instructions

**Your 5 Points (to be encoded in OpenSpec config.yml):**

1. **Every change must have unit tests, E2E test, regression tests** (whether prompted or not)
2. **Changes must end with code review** for style, standard, security
3. **Verification (`/opsx-verify`) must trigger checking of uncovered code** (code not tested)
4. **Commits must be granular** (one fix = one commit)
5. **Tests run in a progressive loop**:
   - Test → Create issue in repo → Fix → Retest + Regression test
   - Loop until all issues fixed

**AI Question:** "Is this for ALL tests, or specifically for E2E/integration tests?"

**Your Clarification:** "I agree. Let us go for a kill only in E2E and Integration."

**AI Concern:** "This workflow can slow velocity. For MVP, start with 'every test must pass before merge' and defer granular issue-loop to phase 2?"

**Your Response:** "Agreed"

**Final Decision:**
- **MVP**: All tests must pass, granular commits, code review
- **Phase 2**: Issue-driven test loop for E2E/integration failures

### Code Coverage Threshold

**AI Question:** "What code coverage % for /opsx-verify?"

**Your Response:** "Let us call it >70%"

**Decision:** >70% code coverage required
- Checked in `/opsx-verify`
- Blocks merge if below threshold

### Data Validation Rules

**AI Question:** "Should we document validation rules in OpenSpec?"

**Your Response:** "OpenSpec document must have all required data. I believe we need it there for verification and regression tests. Thoughts?"

**AI Agreement:** "Absolutely. Rules inform API implementation, test cases, and verification."

**Decision:** Create `validation-rules.md` in OpenSpec changes
- These rules drive Laravel validation
- Inform test case generation
- Used in `/opsx-verify`

### RBAC (Role-Based Access Control)

**AI Question:** "Can a Manager see only their projects, or all projects?"

**Your Clarification:** "Can see all projects. But not allocate to other team's members."

**Decision:** RBAC Matrix defined

| Persona | Can See | Can Modify |
|---------|---------|------------|
| Superuser | All | All |
| Manager | All projects (read-only for others') | Own projects, own team allocations |
| Developer | Own allocations, assigned projects | Own actuals only |
| Top Brass | All reports | Nothing (read-only) |

---

## Deferred Features

### Phase 2 Deferrals

| Feature | Reason for Deferral | Estimated Lift |
|---------|---------------------|----------------|
| **Notifications (WebSocket)** | Allocations are monthly, not time-critical | ~6 hours |
| **PDF/CSV Exports** | On-screen reports sufficient for MVP | ~4 hours |
| **Background Jobs** | No heavy processing in MVP, Laravel Queue ready | ~2 hours |
| **Audit Logging** | No compliance requirement for MVP | ~3 hours |
| **Advanced Caching (pre-calculated reports)** | Start with on-demand queries | ~4 hours |
| **API Versioning (`/api/v1/`)** | Not needed until breaking changes | ~2 hours |
| **Issue-driven test loop** | Slower velocity for MVP | ~8 hours |

### Notifications Deep-Dive

**AI Presented 3 Options:**

**Option A:** Include WebSocket + 1 notification PoC (~6 hours)
- Pros: Real-time updates, framework ready
- Cons: Adds complexity, delays other features by ~1 day

**Option B:** Skip notifications entirely for MVP
- Pros: Keeps scope tight, faster MVP
- Cons: Users must refresh to see changes
- **Debt accrual:** Low (easy to add later)

**Option C:** Polling-based notifications (~2 hours)
- SvelteKit polls every 30s
- Pros: Simple, users see changes quickly
- Cons: Not true real-time, more server load

**AI Recommendation:** Option B (skip for MVP)

**Your Question:** "Wont it become a technical debt? How big the lift will be to at least set up the wiring for notifications (websocket setup and one notification implemented as a proof of concept?)"

**AI Response:** "6 hours total lift. Not worth it for MVP - allocations are monthly, not time-critical."

**Your Decision:** "Ok. Option B."

---

## Rejected Options

### Options Considered but Not Chosen

| Option | Why Rejected |
|--------|--------------|
| **Laravel + Blade Templates** | Less interactive UI, harder to build dashboards |
| **Laravel + Vue.js** | You preferred learning Svelte over Vue |
| **Next.js + Node.js** | You have PHP background, prefer Laravel |
| **SQLite for local dev** | Avoid migration pain, PostgreSQL from start |
| **Session-based auth** | JWT chosen for future mobile support |
| **Multi-tenancy from day 1** | Adds complexity, defer to post-MVP |
| **WebSocket notifications in MVP** | Not time-critical, 6 hours of work |
| **PDF/CSV exports in MVP** | On-screen reports sufficient initially |
| **GraphQL** | REST is simpler for MVP |
| **Chart.js / Plotly / ECharts** | Recharts chosen (good balance) |
| **Shadcn/ui / Svelte Material UI** | DaisyUI chosen (faster development) |
| **Custom-built table component** | TanStack Table chosen (industry standard) |

---

## Open Questions (Resolved)

### 1. Over/Under Forecast Context

**Initial Confusion:** "Is over/under forecast about allocation vs approved estimate, or allocation vs capacity?"

**Your Clarification:** "In the project's context, yes. it is allocation vs approved. (For the future phases, there will be over/under forecast for resources - that will be based on individual's allocation vs their capacity. May be we can keep that aside for now.)"

**Example Correction:**
- **AI Example:** "Month 1 allocation: 80hrs → Under-forecast (OK)"
- **Your Correction:** "Not OK. Because this money is my salary! We always try to be on par - 100%. If it is under-forecast, call that out."

**Resolution:** Both over and under-forecast are flagged. Under is YELLOW, Over is RED.

### 2. Availability Model

**Initial Confusion:** "Is availability 1.0 = 8 hours/day, or is it a percentage?"

**Your Clarification:** "Hours per day must be configurable per project. 1 means, 100% of a productive day. .5 means half of that and so on. I dont want to make it too granular thats why I had stops on 1, .5 and 0. Then there are H - holidays and O- weekend offs."

**Resolution:** Availability is 0, 0.5, or 1.0 (not percentage). 0 = unavailable or PTO.

### 3. Untracked Resource Purpose

**Initial Confusion:** "Is this for contractors, or overhead?"

**Your Clarification:** "We might have some time allocated for DevOps team which is not part of my team but might out bill to another team. For that purpose."

**Resolution:** Untracked resource is for external team time (not billed in this system).

### 4. Team Structure

**Initial Confusion:** "Does 'Team' mean sub-teams?"

**Your Clarification:** "Yes. Read that as 'Role'."

**Resolution:** Team = Role (e.g., Frontend, Backend, QA, PM, Architect).

### 5. Manager Permissions

**Initial Confusion:** "Can a Manager allocate to projects outside their team?"

**Your Clarification:** "Can see. But not allocate to other team's members."

**Resolution:** Managers see all projects (read-only for others'), but can only allocate their own team members.

---

## Timeline

### Conversation Flow

**February 17, 2026:**

1. **Initial Problem Statement** (09:00-09:30)
   - You described the spreadsheet nightmare
   - Identified 4 personas
   - Outlined capacity planning → allocation → actuals flow

2. **Requirements Deep-Dive** (09:30-11:00)
   - Clarified capacity planning details (availability model)
   - Defined project lifecycle states
   - Detailed allocation matrix requirements
   - Discussed reporting needs

3. **Technical Stack Discussion** (11:00-12:00)
   - Debated Laravel vs alternatives → Laravel chosen
   - Frontend: Vue vs Svelte → SvelteKit chosen
   - Database: SQLite vs PostgreSQL → PostgreSQL chosen
   - Authentication: Session vs JWT → JWT chosen

4. **Architecture Decisions** (12:00-13:00)
   - Containerization approach (Docker Compose)
   - Multi-tenancy deferral
   - Caching strategy (Redis from day 1)
   - Real-time updates (polling, defer WebSockets)

5. **Quality Standards** (13:00-13:30)
   - Testing requirements (>70% coverage)
   - Code review process
   - Commit standards (granular)
   - Issue-driven test loop (defer to Phase 2)

6. **Frontend Libraries** (13:30-14:00)
   - UI components: DaisyUI chosen
   - Charts: Recharts chosen
   - Tables: TanStack Table chosen
   - Forms: Superforms + Zod chosen

7. **Final Verification** (14:00-14:30)
   - Reviewed complete architecture
   - Confirmed no missing pieces
   - Decided on API documentation (Scribe)
   - Named the project: **Headroom**

8. **Documentation Request** (14:30-15:00)
   - Request for comprehensive documentation
   - Mermaid diagrams
   - Word document for hardcopy

### Key Turning Points

**Moment 1: Naming the Project**
- You chose "Headroom" over "Margin"
- This crystallized the product's identity

**Moment 2: SvelteKit Decision**
- Despite AI recommending Laravel + Vue (easier)
- You chose SvelteKit (more learning, cleaner separation)
- This showed willingness to learn for better architecture

**Moment 3: Redis from Day 1**
- AI recommended deferring caching
- You insisted on Redis from day 1 (avoid refactoring debt)
- This showed pragmatic technical judgment

**Moment 4: "This money is my salary!"**
- Clarified that under-forecast is NOT acceptable
- Both over and under-forecast must be flagged
- This revealed the business criticality of accurate allocation

**Moment 5: "One last check before we lock in"**
- You paused before committing to the stack
- Requested comprehensive review
- This showed careful, deliberate decision-making

---

## Considerations & Trade-offs

### Decision Matrix

| Decision | Benefit | Cost | Rationale |
|----------|---------|------|-----------|
| **SvelteKit (separate)** | Clean separation, modern framework | Deployment complexity, learning curve | Better long-term architecture |
| **Redis from day 1** | No refactoring debt later | Slightly more upfront setup | Prevents future pain |
| **JWT over sessions** | Mobile-ready, stateless | More complex than sessions | Future-proofing |
| **PostgreSQL from day 1** | No migration later | Heavier than SQLite | Production-grade from start |
| **Defer notifications** | Faster MVP | Users must refresh | Not time-critical for monthly planning |
| **Defer exports** | Tighter scope | No PDF/CSV initially | On-screen reports are primary value |
| **TanStack Table** | Powerful, standard | Learning curve (you're unfamiliar) | Industry best practice |
| **DaisyUI** | Fast development | Opinionated | Speed > customization for MVP |

### Risk Assessment

**Low Risk:**
- Laravel choice (you have PHP background)
- PostgreSQL choice (mature, well-supported)
- Redis choice (simple, well-integrated with Laravel)

**Medium Risk:**
- SvelteKit choice (learning curve, but modern and well-documented)
- TanStack Table (unfamiliar to you, but powerful)
- Two-container deployment (more moving parts, but cleaner)

**Mitigated Risks:**
- **Over-complexity:** Deferred features to Phase 2 (notifications, exports, multi-tenancy)
- **Performance:** Redis caching from day 1
- **Testing debt:** >70% coverage enforced from day 1

---

## Success Metrics (Defined)

### MVP Success Criteria

**Functional Completeness:**
- ✅ Users can define team capacity
- ✅ Users can create projects with approved estimates
- ✅ Users can allocate resources month-by-month
- ✅ Users can log actual hours
- ✅ System validates allocations (over/under warnings)
- ✅ Users can view 5 core reports
- ✅ RBAC enforced (4 personas)

**Quality Metrics:**
- ✅ All tests passing (unit + E2E)
- ✅ Code coverage >70%
- ✅ Zero linting errors
- ✅ API documentation auto-generated

**Usability Metrics (Post-Launch):**
- Manager can complete monthly allocation in <30 minutes (vs 2+ hours in spreadsheet)
- Zero billing errors in first 3 months (over/under caught before invoicing)
- 90% of team members log actuals weekly

**AI Rationale:** "Fair but not too lenient. Manager time savings is measurable. Billing error prevention is critical. Adoption (90%) is achievable but requires discipline."

---

## Appendix: Conversation Highlights

### Most Insightful Moments

**On Under-Forecasting:**
> "Not OK. Because this money is my salary! We always try to be on par - 100%. If it is under-forecast, call that out."

**On Naming:**
> "Headroom. It's the word managers actually say ('do we have headroom for this?'), it immediately signals capacity planning, and it's memorable without being try-hard."

**On Caching:**
> "Query caching and Response caching on Redis from Day 1. No need to sweat on refactoring it everywhere."

**On Quality:**
> "I know this will be a time taking process. But I believe it will be worth it."

**On Final Review:**
> "Now this is the part I am most scared about. If I say yes, we need to stick to this rule book. Did I forget anything?"

### Your Leadership Style

**Observations from conversation:**
- **Pragmatic:** Willing to defer features to keep scope tight
- **Quality-focused:** Insisted on testing, code review, coverage from day 1
- **Deliberate:** Paused multiple times to verify decisions before committing
- **Learning-oriented:** Chose SvelteKit despite unfamiliarity, trusted AI recommendations on unfamiliar tools (TanStack Table)
- **Business-minded:** Constantly connected technical decisions to business impact (billing accuracy, manager time savings)

---

## UI Layout Decisions

**Date:** February 18, 2026  
**Context:** After initial authentication implementation, reviewed login page UI and decided to establish a comprehensive layout system.

### Problem Statement

The initial UI implementation used a simple top-navbar pattern without a standardized layout system. For a data-dense resource planning application, this approach would not scale well.

### Design Direction

**Aesthetic Spectrum Decision:**
- Target: **70% Data-Dense | 30% Utilitarian**
- Reference Apps: **Obsidian** (minimal chrome, content-first) + **Jira** (hierarchical sidebar, dense tables)

### Core Layout Decisions

| Decision | Choice | Rationale |
|----------|--------|-----------|
| **Sidebar** | Collapsible (full ↔ icons-only ↔ hidden) | Preserves screen real estate for low-resolution displays; sidebar should not eat productive space |
| **Month Selector** | Global (in top bar) | Allocation and actuals views are month-centric; affects all views |
| **Default Theme** | Light mode | Starting simple; dark mode available as toggle |
| **Icon Library** | **Lucide Svelte** | Modern, more icon variety, consistent with Svelte ecosystem |
| **UI Framework** | **DaisyUI-first** (no shadcn-svelte) | Already have it, excellent for business apps, use ~80% of its potential |
| **Navigation Pattern** | Persistent sidebar + top bar | Obsidian/Jira style; sectioned navigation (Planning, Reports, Admin) |

### Sidebar Specifications

```
EXPANDED (240px)        COLLAPSED (64px)       HIDDEN (0px)
┌────────────────┐      ┌────────┐            ┌──────────────────┐
│ ◀ ▶            │      │ ▶      │            │                  │
│ ────────────── │      │ ────── │            │   Full width     │
│ PLANNING       │      │        │            │   content        │
│ 📊 Dashboard   │      │ 📊     │            │                  │
│ 👥 Team Mem    │      │ 👥     │            │   (toggle via    │
│ 📁 Projects    │      │ 📁     │            │    Cmd/Ctrl+\)   │
│ 📅 Allocations │      │ 📅     │            │                  │
│ ✅ Actuals     │      │ ✅     │            │                  │
│ ────────────── │      │ ────── │            │                  │
│ REPORTS        │      │        │            │                  │
│ 📈 Forecast    │      │ 📈     │            │                  │
│ 📉 Utilization │      │ 📉     │            │                  │
│ 💰 Costs       │      │ 💰     │            │                  │
│ 📋 Variance    │      │ 📋     │            │                  │
│ ────────────── │      │ ────── │            │                  │
│ ADMIN*         │      │        │            │                  │
│ ⚙️ Settings    │      │ ⚙️     │            │                  │
│ ────────────── │      │ ────── │            │                  │
│ 🌙 Dark [tgl]  │      │ 🌙     │            │                  │
└────────────────┘      └────────┘            └──────────────────┘

* Admin section visible only to superuser role
```

### Responsive Behavior

| Breakpoint | Sidebar Behavior | Toggle |
|------------|------------------|--------|
| ≥1280px (xl) | Expanded by default | Manual toggle only |
| 1024-1279px (lg) | Collapsed by default | Manual toggle only |
| 768-1023px (md) | Hidden (drawer overlay) | Hamburger menu |
| <768px (sm) | Hidden (drawer overlay) | Hamburger menu |

### Implementation Approach

**Phased Changes:**
1. `p00-api-documentation` — Add Scribe annotations to all controllers
2. `p01-ui-foundation` — Types, stores, Lucide setup, theme system
3. `p02-app-layout` — AppLayout, Sidebar, TopBar, Breadcrumbs
4. `p03-dashboard-enhancement` — Dashboard with stat cards
5. `p04-content-patterns` — DataTable, StatCard, FilterBar, EmptyState, LoadingState
6. `p05-page-migrations` — Migrate remaining pages incrementally

### Files to Create

```
frontend/src/lib/
├── types/layout.ts                    # SidebarState, NavItem, NavSection
├── stores/
│   ├── layout.ts                      # sidebarState, theme
│   └── period.ts                      # selectedMonth (global)
├── config/navigation.ts               # Navigation sections config
└── components/layout/
    ├── AppLayout.svelte               # Main layout wrapper
    ├── Sidebar.svelte                 # Collapsible navigation
    ├── TopBar.svelte                  # Search, month, user menu
    ├── Breadcrumbs.svelte             # Navigation context
    └── PageHeader.svelte              # Page title + actions
```

### DaisyUI Table Density

| View | Classes |
|------|---------|
| Allocation Matrix | `table-compact table-pin-rows table-pin-cols` |
| Projects List | `table-zebra table-pin-rows` |
| Team Members | `table-zebra` |
| Reports | `table-compact table-pin-rows` |

### Key Quotes from Discussion

> "I like a collapsible sidebar, because some people use very low screen resolution which will limit the real estate to play around with. Sidebar should not eat up the productive space."

> "Make [month selector] global."

> "Light mode for now."

> "I lean more towards data-dense. How about keeping it 30-70 (utilitarian-data-dense)?"

> "Use Lucide."

---

## Next Steps (Post-Documentation)

### Immediate Actions

1. **Review Documentation**
   - Read Project Charter
   - Review Architecture Document
   - Verify Decision Log captures everything

2. **Formalize in OpenSpec**
   - Create first change: `/opsx-new headroom-foundation`
   - Document proposal, specs, design, tasks
   - Begin implementation

3. **Project Setup**
   - Initialize Laravel project
   - Initialize SvelteKit project
   - Create Docker Compose setup
   - Configure PostgreSQL + Redis

4. **First Sprint (Week 1)**
   - Database schema design
   - Docker Compose working
   - JWT authentication
   - Basic CRUD for team members

---

**Document Control:**
- **Owner:** Santhosh J
- **Type:** Conversation Archive & Decision Log
- **Purpose:** Comprehensive record for future reference
- **Intended Audience:** Santhosh J, Associate
- **Format:** Markdown (for git), Word (for hardcopy)

---

*"This is my magnum opus project as of date."* — Santhosh J, February 17, 2026

---

## Allocation Fidelity Decisions

**Date:** February 26, 2026  
**Context:** During enhanced-allocation discovery, we found drift between intended planning semantics and current implementation assumptions. These decisions lock the canonical model to avoid rework.

### D-ALOC-01: Three-Surface Planning Chain Is Canonical

**Decision:** Allocation planning uses a strict layered model:
1. **Projects surface**: `approved_estimate` is lifecycle total effort cap
2. **Project-Month Plan surface**: manager-entered monthly plan hours per project
3. **Project-Resource Allocation surface**: month execution by team member (and untracked)

**Outcome:** Reporting derives from this chain and must not bypass month-plan semantics.

### D-ALOC-02: Monthly Plan Is Explicit, Not Derived

**Decision:** Do **not** derive monthly budget from `approved_estimate / 12`.

**Rationale:** Delivery phasing depends on external dependencies, customer timelines, and team sequencing; equal split is misleading.

**Example:** A 3000h project may be planned as Jan 1200, Feb 1400, Mar 400.

### D-ALOC-03: Reconciliation Rule for Monthly Plan vs Lifecycle Total

**Decision:** Sum of all project month-plan values is reconciled against project `approved_estimate`:
- `sum > approved_estimate` -> **OVER**
- `sum < approved_estimate` -> **UNDER**
- `sum == approved_estimate` -> **MATCH** (neutral)

**Visual policy:** emphasize over/under; match remains neutral.

### D-ALOC-04: Blank Month Semantics

**Decision:**
- In planning UI, blank month cells remain blank (not auto-filled with 0)
- In allocation variance math, blank plan is treated as planned `0`
- Allocation is allowed even when month plan is blank

**Rationale:** Preserve manager intent in planning UI while keeping deterministic execution math.

### D-ALOC-05: Grid-First Editing Policy

**Decision:** Use grid entry as primary interaction for planning and allocation surfaces.

**Policy:** Modal flow is not primary for single-cell edits.

### D-ALOC-06: Minimal Status Visual Language

**Decision:** Keep status visuals minimal:
- **OVER** = red
- **UNDER** = amber
- **MATCH/SETTLED** = neutral (no extra green spread)

**Guideline:** Status emphasis belongs on row/column summary edges, not heavy color in every interior cell.

### D-ALOC-07: `forecasted_effort` Deprecated for This Workflow

**Decision:** Stop using `projects.forecasted_effort` as planning source for this capability.

**Status:** Development phase; safe to deprecate with no production migration burden.

**New source of truth:** project-month planning dataset for monthly intent.

---

*End of Decision Log*
