Commit c48d969
committed
docs(ai): correct eight claims the code no longer supports (#996)
* docs(ai): correct eight claims the code no longer supports
Every claim on the page was checked against release/2.2.0. The model of the
feature holds -- the schema-shaped guarantee, the routing, the timeouts, the
probe taxonomy and all 27 code-map rows survived. Eight sentences did not.
Two are drift rather than error: the page landed on 2026-08-27, metadata
stripping (#914) hours later the same day, `portion` (#864) three days after.
- **The schema has four fields, not three.** `portion` was missing from the
prose and from the sequence diagram, and the page's own excerpt elided the
comment defending it. It is not inert -- it is a lookup key into the matched
food's own portion list, so the model's word chooses which row is preset. The
grams still come from the database, but a page that tells the reader to audit
the schema has to state what is in it.
- **The encoder fallback does not send the file unmodified.** It strips every
metadata block first -- EXIF GPS above all -- and refuses a file it cannot
parse. The page understated its own protection while asserting something
false, and "unmodified" is the word a privacy reviewer would quote back.
Third bound added; diagram node corrected.
- **1024 px bounds the shortest edge, not the longest.** flutter_image_compress
takes the smaller ratio, so a 4:3 frame leaves at about 1365x1024. The source
comment in meal_photo_encoder.dart carries the same misreading and still
needs its own fix.
- **There is no gallery source.** Only ImageSource.camera is offered; "Camera
or picker" read as "camera or gallery".
- **The photo path has a second gate.** For a server you run it appears only
once the probe's photo leg has passed.
- **Two requests carry a retention instruction on the wire** -- `store: false`
to OpenAI, `data_collection: "deny"` to OpenRouter -- so retention is not
purely a policy question deferred to the README.
- **The probe is not once.** It re-runs on every confirm, deliberately: the
address and model can be identical and the machine behind them different.
- **`rejected` is the provider refusing, not a guardrail.** A plaintext-guard
refusal lands on `unknown`, because nothing was sent and nothing was learned.
- **The schema row cited a test that does not pin it.** The contract test named
asserts a quantity ceiling and would still pass if `calories` were added.
Repointed at the test that actually enumerates the exposed fields.
* docs(ai): answer the questions the page left open, and harden its guard
Second pass over the same review: the GAP and OVERSTATED findings, after the
factually-wrong set. Every addition was verified against release/2.2.0 first,
and three of the reviewer's suggestions turned out to be wrong.
What the page now answers that it did not:
- **What travels with a request.** Model id, system prompt, the line you typed,
the tool and its schema, the answer cap -- and the app language appended to
the prompt as one sentence. Nothing from the diary, profile or history, no
earlier request, no identifier. The negative is structural: `requestItems`
takes a system string and a `MealContent`, so there is no seam to attach one.
- **The other half of the litre story.** Putting `l` in the enum opened the
mirror-image failure -- a model answering with a unit nobody typed, 470 kcal
logged for a glass of milk. `textStatesAUnit` closed it by corroborating any
unit against the text the model was given.
- **What a garbled or truncated reply does.** One bad entry is dropped and the
batch survives; a reply where every entry drops is refused rather than passed
on as an empty list, which would be indistinguishable from "no food here".
Truncation is not a case the app recognises, and the page now says so.
- **Two requests reach a server you run**, and the model-list one goes out
before the consent screen -- it hangs off the address field, not the save
path.
- **What the app asks each destination not to keep** -- `store: false`,
`data_collection: deny` -- with a guardrail row for the latter.
- **The probe sends a fixed line and a bundled photograph**, never anything of
yours, matching the consent screen's wording from #985.
- The `failed --> passed` edge the state diagram was missing, the photo-only
count rule, the onboarding entry point, and the consent invariant's real home
in credential storage rather than in two widgets.
Narrowed where the page claimed more than the code delivers: retraction covers
the photo row only; "the disclosure shown before anything is stored" becomes
"before any credential is stored", since a provider tag and a model id are
written first; and the blanket no-logging sentence now matches what the contract
test actually pins about the three clients.
The page's own guard is hardened alongside it, since it is the only thing still
watching once the page is lifted to the wiki: the link scan read one link form
out of several and silently missed reference-style definitions, the slug
function diverged from GitHub's on underscores and on runs of spaces, a link
resolving outside the repository was mis-resolved rather than failed, and the
canary floor sat at 25 against a real 49. Verified by adding a broken
reference-style link and watching it fail, which it did not before.
* docs(ai): address review — name what the Responses API retains, and read indented fences
Copilot caught both. The retention sentence had no subject: it now says the
Responses API retains request and response content by default, which is the
point of sending `store: false`.
`withoutFences` anchored its fence pattern at column 0, so a fence indented
inside a list item was invisible to it and the sample links and headings in
that fence were scanned as though they were the page's own. CommonMark allows
up to three spaces before a fence, and the closing run needs the same
allowance.
(cherry picked from commit 209e8ee)1 parent ae8ad7c commit c48d969
2 files changed
Lines changed: 379 additions & 67 deletions
0 commit comments