ページ · Health Debug
The 8 Protocol Engines — State Machine Specifications
Project: Health Debug (healthdebug.com) — greenfield build Document: 03 — Protocol Engines (planning only, no implementation) Status: Draft for review. UI-dependent items are flagged inline as PENDING DESIGN. Date: 2026-09-01
Purpose
This document specifies the eight Protocol Engines as backend state machines. Each engine is defined by its purpose, states, transitions, invariants, exact parameters from the product spec, inputs/outputs, a proposed REST API surface (endpoint names only), edge cases, and fail-safe behavior. Every engine is constrained by the Two Core Opinions, and every engine runs only in the ToGO backend, which is the Single Source of Truth (SSOT) for all temporal and state logic. Clients (React web, native Swift, native Kotlin, Electron, Chrome extension) are presentation and sensor-collection layers: they render engine state returned by the API and push sensor/user events to it. They never compute or hardcode protocol logic locally.
0. Global Rules That Bind All Engines
0.1 The Two Core Opinions (non-negotiable)
- The Protocol is Categorical, Not Quantitative. Engines evaluate inputs by what they are, not how much. Food is strictly
SafeorTrigger-bearing. There is no quantitative AI deduction logic for food anywhere in the system. Where an engine has a numeric parameter (e.g., 250ml hydration units, 90-minute caffeine block), the number is a fixed protocol constant, not an input to a quantitative model. - The App NEVER Invents Medical Certainty. No engine, and no AI feature layered on top of engine data, may diagnose, prescribe, or guess drug categories. AI (BYOK, proxied server-side) does behavioral pattern analysis only. Every engine output that could be read as medical advice must terminate in: "Consult your doctor."
0.2 SSOT and client contract
- All timers, windows, cooldowns, counters, and state transitions are computed on the ToGO backend. Time comparisons happen server-side.
- Clients send events (a log entry, a sensor sample, a tap) and receive engine state snapshots (current state, remaining time, counters, violation flags) to render.
- A client showing a countdown may animate locally for smoothness, but the authoritative value is always the server snapshot; on reconnect/refresh, the client discards local extrapolation. PENDING DESIGN: exact refresh/animation cadence per surface (web, watch, extension badge, widgets, CarPlay/Android Auto).
- Push/alert delivery rules per device class are PENDING DESIGN.
0.3 Persistence conventions (from the tech-stack rules)
- PostgreSQL via sqlc + Atlas. Every column NOT NULL with a defined default. Nullable-looking concepts (e.g., "no prediction yet") are modeled as explicit enum states or sentinel defaults, never SQL NULL.
- All schema changes follow the expand-contract migration pattern.
- Engine state is derivable: each engine persists an event log (append-only) plus a materialized current-state row per user for fast reads. The event log is the source for recomputation and for AI behavioral pattern analysis.
- Each engine is its own ToGO plugin (decided 2026-09-01): registered on the Microkernel plugin registry with its own routes, config, and hook subscriptions, so engines are independently manageable and implementable (plugin layout in
04-backend-togo.md§8). Hooks carry cross-engine concerns (intake fan-out, future doctor-restriction overlays — see §10).
0.4 Common state-machine vocabulary
Unless otherwise noted, each engine exposes:
state— the engine's current named state (enum).since— server timestamp the state was entered.next_transition_at— server timestamp of the next scheduled automatic transition (or a sentinel when none).violations— categorical violation records (what rule, when), never quantities-based judgments.
0.5 Undefined-by-spec global items (do not invent)
- Day boundary / reset time: several engines accumulate "per day" (Hydration cap) or anchor to daily events (wake-up, sleep). The spec does not define the reset boundary, timezone handling, or DST behavior. Open question — must be decided before Phase 1 schema freeze.
- Violation UX: whether a categorically disallowed log is rejected by the API or accepted and flagged as a violation is a product decision the spec does not settle. This document assumes accept-and-flag (honest journaling beats forced compliance) but marks it as an open question. The alert rendering of a violation is PENDING DESIGN.
1. Hydration Engine
1.1 Purpose
Track water intake in fixed categorical units and pace intake with a cooldown, so the user builds a steady hydration habit relevant to kidney health and gout prevention.
1.2 Exact parameters (from spec)
| Parameter | Value | Notes |
|---|---|---|
| Unit size | 250 ml | The only loggable increment. Categorical: a log is "one unit of water," not a free-form quantity. |
| Maximum total | 5000 ml | Hard cap (20 units). Spec does not state the accumulation window; assumed daily — see open question §0.5. |
| Entry cooldown | 30 seconds | Minimum gap between two accepted entries. |
1.3 States and transitions
Idle— accepting entries; total < 5000 ml.Cooldown— last accepted entry was < 30 s ago; new entries rejected with a machine-readable reason.Capped— total = 5000 ml; no further entries until the window resets.
1.4 Invariants
- Total is always a multiple of 250 and
0 ≤ total ≤ 5000. - No two accepted entries for the same user are less than 30 s apart (server clock; enforced transactionally).
- Cooldown and cap checks run only server-side. Clients may gray out the button from the snapshot, but the API is the enforcer. PENDING DESIGN: disabled-button/cooldown countdown visual (neon
#00FF33glow behavior in dark mode).
1.5 Inputs / outputs
- Inputs: "log one unit" event (client tap from any surface: web, watch complication, extension, widget, CarPlay/Android Auto voice-safe control — surfaces PENDING DESIGN). No free-text quantity input exists.
- Outputs: snapshot
{ state, total_ml, units_logged, cooldown_remaining, cap_remaining }.
1.6 REST surface (names only)
| Endpoint | Purpose |
|---|---|
POST /v1/engines/hydration/entries | Log one 250 ml unit |
GET /v1/engines/hydration/state | Current snapshot |
GET /v1/engines/hydration/entries | Entry history |
DELETE /v1/engines/hydration/entries/{id} | Undo a mistaken entry (window rules — open question) |
1.7 SQL column sketch (planning artifact)
1.8 Edge cases and fail-safe
- Double-tap / retry storms: cooldown absorbs client retries; idempotency keys on
POSTrecommended. - Offline watch entries synced late: entries carry client capture time, but cooldown/cap are validated against the server-side ordering on ingest; conflicting late entries are rejected or flagged, never silently merged. Exact late-sync policy — open question.
- Fail-safe: on any ambiguity (clock skew, duplicate suspicion) the engine declines to count the entry rather than inflating totals.
1.9 Two Core Opinions applied
- Categorical: intake is counted in identical fixed units — "a unit of water was consumed," never "how much fluid was that really?" No ml free-entry, no beverage-volume inference.
- No medical certainty: the engine never says "you are dehydrated" or ties intake to a diagnosis. Any health-facing narrative from AI over hydration history is pattern description only, ending with "Consult your doctor."
2. Caffeine Block Engine
2.1 Purpose
Enforce the protocol rule that no caffeine is consumed during the first 90 minutes after waking (cortisol-window habit for desk professionals).
2.2 Exact parameters (from spec)
| Parameter | Value |
|---|---|
| Block duration | 90 minutes starting at wake-up |
| Blocked category | Caffeine-bearing items (categorical membership, not mg) |
The wake-up event source (manual "I'm awake" log vs. wearable sleep-end via HealthKit/Health Connect vs. both with precedence) is not defined in the spec — open question.
2.3 States and transitions
AwaitingWake— no wake event yet for the current cycle; caffeine logs are un-evaluable (see fail-safe).Blocked— inside the 90-minute window; caffeine-bearing logs are categorical violations.Clear— window elapsed; caffeine logs are protocol-compliant (subject to other engines, e.g., GERD Window).
2.4 Invariants
- The 90-minute countdown is computed only from the server-recorded wake event; clients never derive "blocked/clear" locally.
- Whether an item "is caffeine" is a lookup against the categorical item catalog (shared with Engine 4) — a boolean membership, never a milligram estimate.
2.5 Inputs / outputs
- Inputs: wake-up event; beverage/food log events (item id from catalog).
- Outputs:
{ state, block_remaining, wake_time, violations_today }. PENDING DESIGN: countdown presentation (dark-mode#00FF33glowing timer per color spec).
2.6 REST surface (names only)
| Endpoint | Purpose |
|---|---|
POST /v1/engines/caffeine/wake | Record wake-up event |
GET /v1/engines/caffeine/state | Current snapshot |
GET /v1/engines/caffeine/violations | Violation history |
(Caffeine consumption itself is logged through the shared intake-log endpoint of Engine 4; this engine evaluates those events.)
2.7 Edge cases and fail-safe
- No wake event logged: the engine cannot place the window. Fail-safe: it does not guess a wake time. Caffeine logs made in
AwaitingWakeare stored and markedunevaluated, and the user is prompted to log wake-up. No retroactive violation is invented. - Multiple wake events (naps, corrections): precedence rule (first vs. latest vs. manual-overrides-sensor) is undefined — open question.
- Wearable clock skew / late sync: server ingest time vs. device sample time reconciliation policy — open question (shared with §1.8).
2.8 Two Core Opinions applied
- Categorical: an espresso and a cola are equally "caffeine-bearing." The engine never computes caffeine mg, half-life curves, or tolerance models.
- No medical certainty: violations are stated as protocol facts ("caffeine during block window"), never as physiological claims. AI commentary on caffeine patterns defers to "Consult your doctor."
3. GERD Window Engine
3.1 Purpose
Protect the pre-sleep digestive window for GERD-prone users: during the 4 hours before sleep, only an explicit whitelist of intake is protocol-compliant.
3.2 Exact parameters (from spec)
| Parameter | Value |
|---|---|
| Window length | 4 hours before sleep |
| Whitelist (ONLY items allowed) | water, chamomile, anise |
The sleep-time anchor (user-configured bedtime, wearable-predicted sleep onset, or user "going to sleep now" event) is not defined in the spec — open question. The window is pre-sleep, so anchoring on a planned/target bedtime is implied, but the source of that target is undefined.
3.3 States and transitions
Open— daytime; GERD window not active; all catalog evaluation deferred to Engine 4 only.WindowActive— inside the 4-hour pre-sleep window; the whitelist is the entire allowed set.Sleeping— between sleep and wake events; intake logs during this state are stored and flagged for review (spec does not define this case — see §3.7).
3.4 Invariants
- The whitelist is closed: exactly
{water, chamomile, anise}. There is no "small amounts are fine" carve-out — quantity is irrelevant by Opinion 1. - Window activation time is computed server-side from the sleep anchor; clients only render
window_starts_at/window_active.
3.5 Inputs / outputs
- Inputs: sleep-anchor configuration/events; intake log events (item id).
- Outputs:
{ state, window_starts_at, window_remaining, allowed_items: [water, chamomile, anise], violations }. PENDING DESIGN: how the window countdown and the whitelist chip UI appear; alert color#FF3333per color spec.
3.6 REST surface (names only)
| Endpoint | Purpose |
|---|---|
GET /v1/engines/gerd/state | Current snapshot incl. window boundaries |
PUT /v1/engines/gerd/sleep-anchor | Set/update the sleep-time anchor |
POST /v1/engines/gerd/sleep | Record actual sleep event |
GET /v1/engines/gerd/violations | Violation history |
3.7 Edge cases and fail-safe
- No sleep anchor set: fail-safe — the engine does not guess a bedtime and reports
state: unanchored, prompting configuration. No violations are generated while unanchored. - Bedtime moved after window started (user postpones sleep): recomputation policy for already-flagged logs is undefined — open question.
- Shift workers / irregular sleep: supported only to the extent the anchor is updated; the engine never infers a schedule.
- Logs during
Sleeping: undefined by spec; proposed handling is store-and-flag-for-review, not auto-violation.
3.8 Two Core Opinions applied
- Categorical in its purest form: the window check is set membership against a 3-item whitelist. "A sip of juice" and "a full meal" are the same violation class.
- No medical certainty: the engine never claims reflux occurred or will occur; it reports window compliance and defers symptom interpretation to "Consult your doctor."
4. Trigger Families Engine
4.1 Purpose
Provide the categorical food/intake catalog underpinning the whole protocol: every catalog item is Safe or Trigger-bearing, and trigger-bearing items belong to trigger families.
4.2 Exact parameters (from spec)
| Parameter | Value |
|---|---|
| Item classification | Strictly binary: Safe / Trigger-bearing |
| Trigger families | Gout, IBS-GERD, Fatty Liver |
Who curates/seeds the catalog (admin team, clinical advisors, future doctor dashboard) is not defined — open question. Whether an item can belong to multiple families simultaneously is not stated; the categorical model naturally allows multi-family membership and this document assumes it — open question to confirm.
4.3 States and transitions
This engine is less a timer and more a classification service + per-user exposure ledger. Item lifecycle:
Per-user, each intake log is evaluated at write time into an exposure record: {item, families[], evaluated_as: safe|trigger, engines_notified[]}.
4.4 Invariants
- No item is ever "70% risky" or "risky above X grams." Classification is binary per family membership.
Unclassifieditems produce no protocol judgment (fail-safe: unknown ≠ safe, unknown ≠ trigger; it is explicitly "unevaluated — consult your doctor if unsure").- Other engines (Caffeine Block, GERD Window) consume this catalog for their own categorical checks (caffeine-bearing flag, GERD whitelist membership).
4.5 Inputs / outputs
- Inputs: intake log events (item id or proposal of a new item); catalog curation operations (admin scope).
- Outputs: item classification lookups; per-user exposure timeline grouped by family (the raw material for AI behavioral pattern analysis).
4.6 REST surface (names only)
| Endpoint | Purpose |
|---|---|
GET /v1/catalog/items | Browse/search categorical catalog |
GET /v1/catalog/items/{id} | Item + family memberships |
POST /v1/catalog/items/proposals | Propose an unclassified item |
POST /v1/intake/logs | Log an intake event (shared entry point evaluated by Engines 2, 3, 4) |
GET /v1/engines/triggers/exposures | Per-user exposure timeline by family |
4.7 SQL column sketch (planning artifact)
4.8 Edge cases and fail-safe
- Free-text food the catalog doesn't know: stored as
Unclassified, no judgment rendered, user told the item is unevaluated. The AI is prohibited from guessing its classification (Opinion 2 by extension of "no invented certainty"); curation is human. - Reclassification of an item: historical exposure records keep the classification as evaluated at log time (audit honesty); recomputation policy — open question.
- Localization: item names via ICU Message Format keys, full RTL Arabic support; never concatenate family labels into sentences in code.
4.9 Two Core Opinions applied
- This engine is Opinion 1 institutionalized: the binary Safe/Trigger model with three named families is the only food logic in the system. No portion sizes, no glycemic math, no purine milligrams.
- Opinion 2: family membership is presented as protocol categorization, never as "this food caused your flare." Correlation narratives from AI are behavioral observations ending in "Consult your doctor."
5. Medication Grace Engine
5.1 Purpose
Give users a humane, flexible window to log scheduled medications, tracking adherence-to-logging without ever reasoning about the drugs themselves.
5.2 Exact parameters (from spec)
| Parameter | Value |
|---|---|
| Grace window | 60 minutes, flexible, for logging a medication |
The anchor semantics are undefined by spec: whether the 60 minutes run strictly after the scheduled time, or ±30 around it, or user-configurable — open question. This document models it abstractly as [window_open, window_close] spanning 60 minutes around/after the scheduled dose time.
5.3 States and transitions (per scheduled dose)
5.4 Invariants
- The engine stores user-entered medication names/schedules verbatim. It never maps a name to a drug class, never validates dosage, never checks interactions (hard Opinion 2 prohibition).
Missedis a logging fact, not a health judgment. The engine never advises taking a missed dose, doubling up, or skipping — any such question is answered only with "Consult your doctor."- Window boundaries computed server-side; reminders fired from server schedule. PENDING DESIGN: reminder/alert presentation across surfaces.
5.5 Inputs / outputs
- Inputs: medication schedule CRUD (name, times — free text/user-defined); "dose taken" log events.
- Outputs: per-dose state, upcoming windows, adherence-to-logging history (for AI behavioral patterning only).
5.6 REST surface (names only)
| Endpoint | Purpose |
|---|---|
POST /v1/medications | Create a medication schedule |
GET /v1/medications | List schedules |
PUT /v1/medications/{id} | Update schedule |
POST /v1/engines/medgrace/doses/{id}/log | Log a dose within/after grace |
GET /v1/engines/medgrace/state | Today's dose windows and states |
5.7 Edge cases and fail-safe
- Timezone travel mid-schedule: dose anchoring policy — open question (shared with §0.5).
- Duplicate log for the same dose window: second log rejected as duplicate, kept in audit trail.
- Fail-safe: when the engine cannot determine which scheduled dose a log belongs to, it stores the log unattached and asks the user, rather than guessing.
5.8 Two Core Opinions applied
- Categorical: a dose is
Logged/Missed/LateLogged— never "80% adherent by mg." - Opinion 2 is at its strictest here: no drug-category guessing (explicitly prohibited by spec), no prescribing, no interaction warnings. The engine is a logging clock, and every medication-related uncertainty routes to "Consult your doctor."
6. Cycle Engine (Fertility)
6.1 Purpose
Track menstrual cycles and offer predictions only once enough consistent user-logged data exists, failing safe to "no prediction" whenever the data is irregular.
6.2 Exact parameters (from spec)
| Parameter | Value |
|---|---|
| Calibration requirement | 3 consecutive logged cycles before any prediction is made |
| Irregularity rule | On irregularity, the engine fails safe: no prediction |
The quantitative definition of "irregularity" (e.g., variance threshold in days) is not defined in the spec — open question. Until defined, the planning assumption is that any break in consecutive logging resets calibration, and any detected irregularity suspends predictions entirely.
6.3 States and transitions
Insufficient— fewer than 3 consecutive logged cycles. Output: no prediction, ever. The UI shows calibration progress only (PENDING DESIGN).Calibrated— prediction available and clearly labeled as an estimate.Suspended— irregularity detected; predictions are withdrawn, not "widened." Whether recalibration requires a full fresh 3-cycle run is implied by fail-safe posture but not explicit in spec — open question.
6.4 Invariants
- No prediction leaves the API in
InsufficientorSuspendedstates. The prediction field carries an explicitunavailablesentinel (NOT NULL rule: sentinel, not SQL NULL), plus a reason code. - "Consecutive" means no unlogged cycle between logged ones; the engine never infers a skipped cycle happened.
- Predictions are never framed as fertility guarantees or contraceptive advice (Opinion 2); accompanying copy defers to "Consult your doctor."
6.5 Inputs / outputs
- Inputs: cycle start/end log events (user-entered).
- Outputs:
{ state, consecutive_cycles_logged, prediction: value|unavailable, reason }.
6.6 REST surface (names only)
| Endpoint | Purpose |
|---|---|
POST /v1/engines/cycle/logs | Log a cycle event |
GET /v1/engines/cycle/state | Calibration state + prediction-or-unavailable |
GET /v1/engines/cycle/history | Logged cycle history |
6.7 Edge cases and fail-safe
- Backfilled cycles: whether historical backfill counts toward "consecutive" — open question. Fail-safe default: backfill is stored but calibration counts only forward-logged cycles unless product decides otherwise.
- Contradictory edits (user edits a past cycle making history irregular): engine drops to
Suspendedimmediately — it prefers withdrawing a prediction over defending one. - Fail-safe is the headline rule: ambiguous data → no prediction. The engine never smooths, averages away, or "best-guesses" an irregular history.
6.8 Two Core Opinions applied
- Categorical: state is
Insufficient/Calibrated/Suspended— the user never sees a confidence percentage. - Opinion 2: predictions are behavioral-data extrapolations explicitly labeled non-medical; anything touching fertility decisions, symptoms, or contraception efficacy ends in "Consult your doctor."
7. Contraceptive Security Engine
7.1 Purpose
Track contraceptive method adherence with per-method state machines, because a daily pill, a monthly injection, and a long-term implant have fundamentally different schedules and failure modes.
7.2 Exact parameters (from spec)
| Parameter | Value |
|---|---|
| Differentiated method types | Daily pills, monthly injections, implants |
The spec defines only that the engine differentiates these three types. Per-type details (pill-time grace rules, injection due-date windows, implant validity duration/expiry reminders) are not defined — open questions. The sketches below model only the structural differentiation.
7.3 States and transitions (per active method)
7.4 Invariants
- Method type is a closed enum:
daily_pill | monthly_injection | implant. The engine's logic branches on what the method is (categorical), never on hormone dosage or brand pharmacology. - On any missed/overdue state the engine reports the logging fact and never states protection status ("you are/aren't protected") — that is invented medical certainty. The only guidance emitted is "Consult your doctor."
- Reminder scheduling is server-side. PENDING DESIGN: reminder surfaces and privacy presentation (lock-screen discretion, watch complications).
7.5 Inputs / outputs
- Inputs: method selection/CRUD; dose/injection/replacement log events.
- Outputs: per-method state snapshot, upcoming due items, missed/late history.
7.6 REST surface (names only)
| Endpoint | Purpose |
|---|---|
POST /v1/engines/contraceptive/methods | Register a method (typed) |
GET /v1/engines/contraceptive/state | Current per-method snapshot |
POST /v1/engines/contraceptive/events | Log dose / injection / replacement |
GET /v1/engines/contraceptive/history | Adherence-to-logging history |
7.7 Edge cases and fail-safe
- Method switching (pill → injection): old method archived, new state machine instantiated; overlap semantics — open question.
- Interaction with Cycle Engine: whether an active contraceptive method should suspend cycle predictions is not in the spec — open question; fail-safe posture suggests suspension, but this must be a product/clinical decision, not an engine guess.
- Fail-safe: when due-date math is ambiguous (e.g., missing injection date), the engine reports
unconfigured/ambiguousand asks the user; it never assumes protection continuity.
7.8 Two Core Opinions applied
- Categorical: three method types, each with a small closed state set; no efficacy percentages, no hormone-level modeling.
- Opinion 2: the engine tracks logging events only. All protection, side-effect, and missed-dose consequences route to "Consult your doctor."
8. Kinetic Pomodoro Engine
8.1 Purpose
A desk-work timer for the core audience (programmers/engineers) whose defining feature is that a break only registers if wearables detect physical movement away from the screen — sitting through the break with the timer running does not count.
8.2 Exact parameters (from spec)
| Parameter | Value |
|---|---|
| Break validation | Break registers only if wearable motion data shows physical movement away from the screen |
Not defined in spec (do not invent): work-interval length, break length, the quantitative motion threshold (steps/distance/duration), and long-break cycles. Classic 25/5 Pomodoro numbers are not in the spec and must not be assumed — open questions for product + design.
8.3 States and transitions
8.4 Invariants
- The verification decision is made only on the backend, from motion data that watchOS/WearOS clients read on-device (HealthKit / Health Connect) and push securely to the ToGO API. The watch never decides "break valid" locally — it is a sensor-collection layer.
- A break with no motion evidence is
BreakNotRegistered— absence of data is never treated as movement (fail-safe direction: don't credit). - The desk-side clients (web dashboard, Electron, Chrome extension) render timer state from server snapshots; the extension's role at the "screen" side (e.g., detecting continued browsing during break) is not specified — open question, and any such signal would still be evaluated server-side.
- PENDING DESIGN: timer visuals (dark mode
#1A1A1Abackground,#00FF33neon glow for the active timer,#00CCFFactive buttons; light mode#20A060/#0070A0flat), plus how an unregistered break is communicated without shaming.
8.5 Inputs / outputs
- Inputs: session start/stop; server-scheduled interval elapses; motion data batches pushed from watch clients.
- Outputs:
{ state, interval_remaining, break_status: pending|verifying|registered|not_registered, todays_registered_breaks }.
8.6 REST surface (names only)
| Endpoint | Purpose |
|---|---|
POST /v1/engines/pomodoro/sessions | Start a session |
POST /v1/engines/pomodoro/sessions/{id}/stop | End a session |
GET /v1/engines/pomodoro/state | Current timer/break snapshot |
POST /v1/sensors/motion/batches | Wearable motion data ingest (shared sensor ingest, consumed by this engine) |
GET /v1/engines/pomodoro/history | Session and break-verification history |
8.7 Edge cases and fail-safe
- User has no wearable: every break is
BreakNotRegistered/unverified. Whether a degraded no-wearable mode exists (e.g., honor-system breaks marked as such) is a product decision — open question; the spec's stance implies breaks simply do not register without wearable evidence. - Watch offline during break, syncs later: retroactive upgrade of
BreakNotRegistered → BreakRegisteredon late evidence — allowed in principle (evidence is evidence); exact re-evaluation window — open question. - Motion during break that is not "away from screen" (e.g., fidgeting at desk): the criteria distinguishing qualifying movement are undefined — open question; fail-safe default is to not credit borderline data.
- Fail-safe: all ambiguity resolves to "break not registered." The engine under-credits rather than over-credits.
8.8 Two Core Opinions applied
- Categorical: a break is
RegisteredorNot Registered— binary, no "70% of a break" or movement-quality scoring surfaced to the user. - Opinion 2: the engine makes no claims about musculoskeletal or cardiovascular benefit; AI summaries of sitting/break patterns are behavioral observations ending in "Consult your doctor."
9. Cross-Engine Architecture Notes
9.1 Shared intake pipeline
Engines 2 (Caffeine), 3 (GERD), and 4 (Trigger Families) all evaluate the same intake log event through the categorical catalog. One POST /v1/intake/logs fan-outs via ToGO Microkernel hooks to each engine's evaluator; each engine records its own verdict independently. A single cola at 10 p.m. can simultaneously be: caffeine-compliant (block elapsed), a GERD-window violation (not whitelisted), and a trigger-family exposure — three categorical facts, no arithmetic.
9.2 Proposed backend module layout (planning sketch)
(Exact ToGO project conventions to be confirmed against the ToGO Framework scaffolding in Phase 1; the old togo-based repo at github.com/fadymondy/health-debug is reference-only and nothing is inherited from it.)
9.3 Sensor ingest boundary
- Apple HealthKit and Google Health Connect are read on-device by the native clients; normalized samples are pushed to
POST /v1/sensors/...endpoints. The backend never pulls from Apple/Google directly. - Engines consume normalized sensor events (wake/sleep candidates, motion batches) but the decision to transition state is always the engine's, server-side.
9.4 AI layer relationship
- AI (BYOK: OpenAI, Anthropic, Google, Apple Intelligence; keys encrypted server-side; all calls proxied by the backend; keys never reach clients) reads engine event logs and snapshots for behavioral pattern analysis only.
- AI may never: reclassify catalog items, alter engine state, generate predictions the Cycle Engine has withheld, name drug categories, or produce diagnostic/prescriptive text. Every AI output surface carries the "Consult your doctor" terminal deferral.
9.5 i18n and rendering constraints on engine outputs
- All engine-facing strings are ICU Message Format keys; no concatenation. Counts/durations use ICU plural/select so Arabic plural rules work.
- Progress and countdown renderings must mirror correctly in RTL (including progress bars) — PENDING DESIGN for each surface.
10. Future-State Hooks (context only — NOT current scope)
- Doctor "Medical Restrictions": the future doctor dashboard will prescribe restrictions (blocking foods, enforcing fasting, requiring tracked workouts) that dynamically alter engine behavior (e.g., extending the GERD whitelist restriction set, adding blocked catalog items per patient). Engines should therefore read their rule sets through the Microkernel config/hook layer rather than hardcoding them, so a restriction overlay can be applied later without engine rewrites. Design of that overlay is out of scope here.
- Gamification: badges for protocol compliance (e.g., perfect GERD window) will consume engine violation/compliance streams; engines only need to keep those streams queryable.
- B2B / marketplace APIs: aggregate, consented views over engine data for pharmacies, insurers, wellness clinics — out of scope; noted so engine event logs are designed as clean, exportable streams.
11. Consolidated Open Questions
- Day/window reset boundary and timezone/DST policy for Hydration cap, wake/sleep cycles, and dose schedules.
- Violation handling model: reject at API vs. accept-and-flag (this doc assumes accept-and-flag).
- Wake-up event source and precedence (manual vs. wearable) for the Caffeine Block.
- Sleep-time anchor source for the GERD Window (configured bedtime vs. wearable vs. explicit event) and recompute policy when bedtime shifts.
- Medication Grace anchor semantics: 60 minutes after scheduled time, or centered on it?
- Cycle Engine: quantitative definition of "irregularity"; whether recalibration after
Suspendedrequires a fresh 3-cycle run; whether backfilled cycles count. - Contraceptive Security: per-type window rules (pill day-window, injection due tolerance, implant validity duration); interaction with Cycle Engine predictions.
- Kinetic Pomodoro: work/break interval lengths, qualifying-motion criteria, late-sync re-evaluation window, and no-wearable degraded mode.
- Catalog governance: who curates Safe/Trigger classifications and multi-family membership policy.
- Undo/edit windows for logged entries (hydration undo, cycle edits) and their effect on already-evaluated state.
- All alerting/notification UX and every visual treatment flagged PENDING DESIGN above await the finalized Figma design.