Skip to content

feat: PHIE Phase 1 — Personal Health Intelligence Engine (backend) - #59

Merged
silver-snoopy merged 5 commits into
masterfrom
feature/phie-phase1
Apr 11, 2026
Merged

feat: PHIE Phase 1 — Personal Health Intelligence Engine (backend)#59
silver-snoopy merged 5 commits into
masterfrom
feature/phie-phase1

Conversation

@silver-snoopy

Copy link
Copy Markdown
Owner

Summary

Backend-only correlation discovery + trajectory projection engine for personal health data. Introduces a new intelligence layer that runs automatically after each weekly report, surfacing patterns the user didn't explicitly ask for, and makes them queryable via REST + AI chat tools.

  • Correlation discovery: Pearson r + two-tailed t-distribution p-value across a fixed set of nutrition→biometric candidate pairs, with confidence classification and idempotent upserts (preserves first_detected_at across re-runs).
  • Trajectory projection: OLS linear regression with proper prediction intervals (σ·√(1 + 1/n + (x*−x̄)²/SSxx)) — confidence bands widen with distance from the observed mean.
  • Integration: Fires non-blockingly at the end of both sync and async report generation paths. Failures log under [intelligence] and do NOT affect the returned report.
  • API: GET /api/correlations (filters: category, confidence, status, metric, minConfidence, top) and GET /api/projections/:metric.
  • AI tools: query_correlations, predict_trajectory, simulate_change. Length-bounded inputs; `parseDate` sanitized to avoid leaking raw prompt-injected values to logs.

Commits

SHA Phase
`59175db` 3 Design-check stubs (types, migration, route skeletons)
`482ac19` 4 Implementation (correlation engine, stats, projector, AI tools)
`dc12d28` 6 Fix 3 HIGH + 9 MEDIUM findings from parallel code review
`903df3d` 7 Wire intelligence into both report paths + engine/projector unit tests
`0901d04` 8 Docs: `product-capabilities.md` §4, `architecture.md` updates

21 files changed, +2092 / −2 lines.

Test coverage

  • 344 backend + 52 frontend = 396 tests green, 0 regressions
  • New tests: stats (Pearson / p-value / classification / linear regression / projection), correlation engine (14+ day positive case, min-data-points skip, zero-data), projector (30-day bands widening, skip, early return), routes (15 cases), non-blocking report test (asserts 200 when intelligence rejects)

Acceptance criteria — verified

  • AC1 Migration creates `correlations` + `projections` with CHECK constraints and composite unique indexes
  • AC2 Pearson returns 1.0 perfect / 0 uncorrelated
  • AC3 `runCorrelationAnalysis()` with 14+ days produces ≥1 correlation
  • AC4 `runTrajectoryProjections()` generates 30-day projections with confidence bands
  • AC5 Report generation triggers correlation analysis without blocking on failure
  • AC6 `GET /api/correlations` returns stored correlations; filters work
  • AC7 `GET /api/projections/:metric` returns projections
  • AC8 AI chat calls `query_correlations` tool (mechanics verified; end-to-end value emerges after first post-report run)
  • AC9 344 tests passing, zero regressions in the 289 pre-PHIE suite
  • AC10 Fastify plugin pattern, `.js` imports, `import type`, test mock convention all matched

Phase 1 limitations (documented)

  • No scheduled cron yet — correlations are only discovered after a report is generated. Users who never generate a report will never see correlations. Follow-up ticket should add a nightly run.
  • Backend only — no dedicated correlations/projections UI. Surface is chat + (future) report integration.
  • Dead filter field ≠ silent bug: fixed in the Phase 6 review pass — `metric` and `minConfidence` filter fields are now wired through to SQL.

Migration required

New migration: `010_intelligence.sql` — creates 2 tables, 5 indexes. Must run before deploying this branch.

Test plan

  • Pull branch locally, run `docker compose up -d` + apply migrations, start backend
  • Seed or import enough historical data (≥14 days of nutrition + biometrics) to produce at least one correlation
  • `POST /api/reports/generate?sync=true` → confirm report returns 200, then `GET /api/correlations` shows ≥1 row
  • `GET /api/projections/weight_kg` returns 30 rows with widening bands
  • Chat: ask "what patterns have you found?" → confirm AI invokes `query_correlations`
  • Chat: ask "what happens if I hit 2200 kcal every day?" → confirm AI invokes `simulate_change`
  • Confirm failing correlation analysis (e.g., by breaking a query temporarily) does NOT fail report generation

🤖 Generated with Claude Code

silver-snoopy and others added 5 commits April 7, 2026 01:34
Scaffolded by Sonnet subagent via ADE v4 design check phase.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full implementation of the Personal Health Intelligence Engine services
on top of the Phase 3 stubs: Pearson correlation + p-value stats,
correlation discovery engine, linear trajectory projector with
confidence bands, AI chat tool integration (query_correlations,
query_projections), and intelligence query layer. Phase 5 quality
gate passed: build clean, 332 backend tests green.
Addresses 3 HIGH and 9 MEDIUM findings from parallel code review:

HIGH
- correlation upsert no longer overwrites first_detected_at on re-run
- /api/correlations top query param capped at 100 (prevents DoS)
- remove stale TODO comments from fully-implemented route handlers

MEDIUM — logic
- linearRegression returns r2=0 (not 1) on zero-variance y series
- confidence bands use proper OLS prediction interval formula
  (propagates meanX and ssXX from linearRegression)
- trajectory projector returns early on empty metric filter instead
  of firing useless DB queries against missing defaults
- listCorrelations now honors metric and minConfidence filters

MEDIUM — conventions
- strip apiKeyMiddleware from GET routes (matches sibling convention:
  GET open, POST protected)
- remove @deprecated tags on newly-implemented filter fields
- auto-format correlation-engine.ts per Prettier

MEDIUM — security
- length-bound :metric path param and LLM-supplied metric tool args
- parseDate throws generic 'Invalid date' to avoid leaking raw
  (potentially prompt-injected) input via error logs
Closes Phase 7 verification gaps against AC3, AC4, AC5.

- Wire runCorrelationAnalysis + runTrajectoryProjections into
  generateWeeklyReport as a non-blocking post-save step. Failures
  are logged under [intelligence] prefix and do not affect the
  returned report.
- Also wire into runReportInBackground (async path) with the same
  non-blocking try/catch pattern.
- Add correlation-engine.test.ts with coverage for: 14+ days
  produces >=1 strong correlation, <MIN_DATA_POINTS produces
  none, zero-data path is graceful.
- Add trajectory-projector.test.ts with coverage for: 30-day
  projection with widening confidence bands, min-data-points
  skip, empty-metric early return.
- reports.test.ts: add mocks for intelligence modules and a new
  test asserting report generation returns 200 when the
  correlation analysis rejects.
Add Intelligence section (UC-INT-01..05) to product-capabilities.md
covering correlation discovery, trajectory projection, REST endpoints,
and AI chat tools. Documents Phase 1 limitations (backend-only, no
scheduled run yet — follow-up ticket).

Update architecture.md:
- Add correlations and projections tables to the Data Model inventory
- Add GET /api/correlations and GET /api/projections/:metric endpoints
- Note non-blocking intelligence pipeline in the report generation flow
@vercel

vercel Bot commented Apr 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
vitals Ignored Ignored Apr 11, 2026 7:41pm

@silver-snoopy
silver-snoopy merged commit c09d042 into master Apr 11, 2026
5 checks passed
@silver-snoopy
silver-snoopy deleted the feature/phie-phase1 branch April 11, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant