From 2676a5c02a8366431427e8649c795f2f12bfe023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 10 Sep 2026 15:36:54 +0200 Subject: [PATCH] docs(api): say in the contract that cycle insights are fenced per section The route's description told a native client only that phase never leaves the cycle routes. It now says what a grant scoped to the cycle alone receives: the phase rows with no measurement or mood outcome columns and no lagged discovery, the same as a record with nothing logged. The owner and a whole-record grant are unchanged. The catalogue's header read as a current count; it is history and now says so. --- docs/api/openapi.yaml | 6 +++++- src/lib/openapi/error-codes.ts | 9 +++++---- src/lib/openapi/routes/cycle.ts | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index 54b25d055..e389ba754 100644 --- a/docs/api/openapi.yaml +++ b/docs/api/openapi.yaml @@ -581,7 +581,11 @@ paths: temperatures), plus the single headline finding (resting-heart-rate-by-phase, falling back to HRV). The same Welch t-test + Benjamini-Hochberg machinery the mood-factor crosstab runs; only rows with p < 0.05 AND q ≤ 0.10 surface. Strictly gender-gated — phase never appears on the general `/api/insights/correlations` route. - Observational only, never causal. Gated: `cycle.disabled` 403 when the feature is off." + Observational only, never causal. Gated: `cycle.disabled` 403 when the feature is off. Declared for the `cycle` + section; the outcome columns are fenced per section at the query, so a grant scoped to the cycle alone receives + the phase rows with no `lutealAvg` / `follicularAvg` / `delta` for measurement or mood outcomes and no lagged + discovery, exactly as a record with nothing logged would read. The owner and a whole-record grant are + unchanged." responses: "200": description: Phase-correlation rows + headline. diff --git a/src/lib/openapi/error-codes.ts b/src/lib/openapi/error-codes.ts index dd062e9f2..042a10e8e 100644 --- a/src/lib/openapi/error-codes.ts +++ b/src/lib/openapi/error-codes.ts @@ -4,10 +4,11 @@ * `meta.errorCode` is the mechanism this API chose for machine-readable errors * — the envelope's own description tells a client to branch on it rather than * on the prose — and until this file existed a client could not enumerate it. - * Sixteen of the two hundred and forty-two codes appeared somewhere in - * `docs/api/openapi.yaml`; the rest existed only in server source, so the only - * way to learn one was to trigger the error in testing and the only way to - * learn a new one had appeared was to trigger that too. + * When this file was written, sixteen of its two hundred and forty-two codes + * appeared somewhere in `docs/api/openapi.yaml`; the rest existed only in + * server source, so the only way to learn one was to trigger the error in + * testing and the only way to learn a new one had appeared was to trigger + * that too. * * The list is generated from the code and then committed as a literal, so it is * reviewable in a diff and stable across a release. `error-code-catalogue.test.ts` diff --git a/src/lib/openapi/routes/cycle.ts b/src/lib/openapi/routes/cycle.ts index f251500e6..f0d03b608 100644 --- a/src/lib/openapi/routes/cycle.ts +++ b/src/lib/openapi/routes/cycle.ts @@ -874,7 +874,7 @@ export const cyclePaths: NonNullable = { tags: ["Cycle"], summary: "Cycle-phase correlation insights (v1.15.0)", description: - "FDR-guarded luteal-vs-follicular phase contrast per outcome metric (RHR / HRV / sleep / steps / weight / temperatures), plus the single headline finding (resting-heart-rate-by-phase, falling back to HRV). The same Welch t-test + Benjamini-Hochberg machinery the mood-factor crosstab runs; only rows with p < 0.05 AND q ≤ 0.10 surface. Strictly gender-gated — phase never appears on the general `/api/insights/correlations` route. Observational only, never causal. Gated: `cycle.disabled` 403 when the feature is off.", + "FDR-guarded luteal-vs-follicular phase contrast per outcome metric (RHR / HRV / sleep / steps / weight / temperatures), plus the single headline finding (resting-heart-rate-by-phase, falling back to HRV). The same Welch t-test + Benjamini-Hochberg machinery the mood-factor crosstab runs; only rows with p < 0.05 AND q ≤ 0.10 surface. Strictly gender-gated — phase never appears on the general `/api/insights/correlations` route. Observational only, never causal. Gated: `cycle.disabled` 403 when the feature is off. Declared for the `cycle` section; the outcome columns are fenced per section at the query, so a grant scoped to the cycle alone receives the phase rows with no `lutealAvg` / `follicularAvg` / `delta` for measurement or mood outcomes and no lagged discovery, exactly as a record with nothing logged would read. The owner and a whole-record grant are unchanged.", responses: { "200": { description: "Phase-correlation rows + headline.",