fix(openapi): declare the body-cap 413 and the outbound-screen 502 of a briefing generation

Both have always been answered; neither was declared. The parity walk now
checks them against the contract instead of skipping it.
This commit is contained in:
Marc-André Bombeck committed 2026-10-23 15:53:59 +02:00
1 parent 31048e5e63
commit 18ff14ba1a
3 files changed
+24 -12

No files matched your search

+13
View File
@@ -12654,6 +12654,12 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"413":
description: The request body is over 16 KB. Nothing was generated.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"422":
description: No AI provider can serve the `briefing` capability (`meta.errorCode` = `ai.provider.none`, `meta.reason` =
`no_provider`), or the provider answered something that was not valid JSON (`meta.errorCode` =
@@ -12672,6 +12678,13 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"502":
description: The generated briefing did not pass the outbound safety screen and was discarded (`meta.errorCode` =
`insights.generate.outboundScreened`). Regenerating may succeed.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"503":
description: "Every provider in the chain failed for a reason that is not a rate limit — auth, timeout or an upstream
5xx. A dated failure marker is written, so the read GET reports the briefing as held rather than fresh.
+9
View File
@@ -276,6 +276,15 @@ export const insightsPaths: NonNullable<ZodOpenApiObject["paths"]> = {
"Every provider in the chain failed for a reason that is not a rate limit — auth, timeout or an upstream 5xx. A dated failure marker is written, so the read GET reports the briefing as held rather than fresh. Also: the `briefing` capability could not be resolved (`meta.errorCode` = `ai.unavailable`, `meta.reason` = `check_failed`); nothing was generated.",
content: { "application/json": { schema: errorEnvelope } },
},
"413": {
description: "The request body is over 16 KB. Nothing was generated.",
content: { "application/json": { schema: errorEnvelope } },
},
"502": {
description:
"The generated briefing did not pass the outbound safety screen and was discarded (`meta.errorCode` = `insights.generate.outboundScreened`). Regenerating may succeed.",
content: { "application/json": { schema: errorEnvelope } },
},
"401": stdResponses["401"],
},
},
@@ -745,11 +745,7 @@ describe("POST /api/insights/generate parity", () => {
it("P03 a body over the cap", async () => {
await resetBriefing(OWNER_ID);
await post(
"P03-body-too-large",
{ pad: "x".repeat(17 * 1024) },
{ undeclared: "the body cap answers 413, which the contract omits" },
);
await post("P03-body-too-large", { pad: "x".repeat(17 * 1024) });
});
it("P04 a cached briefing written today", async () => {
@@ -984,13 +980,7 @@ describe("POST /api/insights/generate parity", () => {
"Your 10-year cardiovascular risk is elevated — consider stepping your dose up.",
}),
});
await post(
"P29-outbound-screened",
{ force: true },
{
undeclared: "the outbound screen answers 502, which the contract omits",
},
);
await post("P29-outbound-screened", { force: true });
});
it("P30 the about-me text changing during the generation", async () => {