Repository navigation
Six tickets and twenty-one review items, in three batches. One change is
breaking: a coordinate outside the range of the globe is now refused rather
than turned into a number that looks like a distance. The rest close the
supply-chain gate CUI-0036 left half-built, give a bounds refusal a
machine-readable name for the argument it refused, and pay off a run of
figures that had been quoted in comments with nothing holding them to a
number.
Breaking
haversine_distancescreens for a range now, not only for finiteness: a
latitude outside-90..90or a longitude outside-180..180raises
ValueErrorreadingout-of-range coordinate, soparse_alllogs the file
by name at WARNING and drops it rather than letting it contribute. Before,
lat=400answered 4,447.8 km and nothing downstream could tell that from a
real reading; push the magnitude to around1e308-- finite, so CUI-0008's
screen passed it -- andnp.sinoverflowed back tonan, whichpandas
drops out of a sum, reopening the exact CUI-0001 shape where a track
silently reports short. The bounds are inclusive: the poles and the
antimeridian are real places and stay valid. The four range tests replace
the fourmath.isfinitecalls rather than joining them --abs(nan)is
nanand loses every comparison, and no infinity survives<= 90.0-- so
the check count is unchanged and thenan/±infmessage is unchanged byte
for byte. On the real export (356 tracks, 97,003 points) the old and new
guards answer identically for every one, so this breaks corrupt input only
(CUI-0047).
Added
- A bounds refusal now carries
extensions.argument, naming which argument
was refused:"limit","offset"or"points".path,locationsand
extensions.codeare identical forlimitandoffseton the same field,
so branching on the code -- which the SDL tells clients to do -- could not
tell a client which of the two to correct. The value is a hard-coded literal
at each of the three raise sites, never interpolated from the request, and
it is the schema name rather than the alias (CUI-0050, following W-035). pip-auditruns in CI, as the last step oflint-test, preceded by
python -m pip install --upgrade pip setuptools. It audits the whole
environment -- the ten runtime dependencies, the[dev]extras and
pip-audit's own closure -- and reports none. Flask and Strawberry are core
dependencies that go straight into the Vercel runtime, and nothing had been
auditing them. An--ignore-vulnallowlist was considered and rejected on
the grounds W-034 and S-095 already established: a list of exceptions drifts,
and the gate then reports on the list rather than on the tree (CUI-0044).
Changed
npm auditruns over the whole tree; the--omit=devCUI-0036 shipped with
is gone. The fourteen advisories that flag hid were real, and they are fixed
rather than filtered:@graphql-codegen/cli5 to 7,client-preset4 to 6
andvitest3 to 5 takelodashout of the dependency tree entirely, and
the full-tree audit now reports zero. This closes the last open half of
CUI-0036 (CUI-0049).client-preset6 no longer emits schema-wide types.Maybe,InputMaybe,
Scalarsand every schema type are gone fromfrontend/src/gql/graphql.ts,
which keeps operation and fragment types and the*Documentconstants. Only
frontend/src/data/api/queries.tsimports from@/gqltoday, and only for
thegraphqlhelper, sotsc -bis unaffected; animport type { Activity } from "@/gql"added later will not resolve and belongs in
src/data/types.ts. AnIDinput is nowstring | number(CUI-0049).
Fixed
- The key set a refusal publishes in
extensionshas a gate. CUI-0050 turned
a literalextensions={code}-- where "nothing but the code" held by
construction -- into a dict built up across two statements, which makes the
invariant one that can be lost; a mutant adding a third key left all 573
tests of the day green and still reached the wire. The existing guard is a
denylist of three counter names, so a key under any other spelling walked
past it. The new test is an allowlist over the same documents the codes and
the arguments are held over, and it fails at every one of its parameters
under that mutant (W-050).
Documented
tracks()treats-0.0as zero, which is what the Args section always
said;-0.0 < 0isFalseand-0.0is falsy, so both paths agree. That
was filed as a defect and settled as not one, with tests pinning the five
values that mean "every row" and the negatives that are refused. Afloat
that reaches the sampler raisesTypeError, which nothing had written down
-- and it is any suchfloat, not only a fractional one:2.0raises as
surely as2.5, while1.5,1000.5and0.0do not, each for a
different reason now recorded in the docstring (CUI-0048, S-106, S-130).- The SDL says which of
limitandoffseta refusal names when both are
out of range --limitis checked first -- and where a request with several
bad windows is refused: at the first such field in document order, not at a
privileged field. Both are pinned by tests that run the orders in both
directions, because a test on one order records the wrong rule and stays
green (S-103, S-104, S-129). - Figures quoted in comments are pinned to the commit they were measured at,
or removed. The CUI-0038 comment no longer quotes byte counts without saying
which document produced them;CLAUDE.md§6 no longer offers codegen line
counts as a baseline, since they were short by the six-line preamble and
even the percentage moves with the counting method; and three suite sizes
quoted intests/test_api.pynow name the commit where collecting the suite
reproduces them (CUI-0051, W-060, W-061, S-105, S-128). docs/deployment.mdstates what the audit gates actually cover, including
pip-audit's own closure, and that both sit upstream ofdeploy-- so an
advisory in a package this project never touches can hold a deployment,
including a hotfix.CLAUDE.md§3 carries the pip upgrade line that CI runs,
without which the same command reports fourteen advisories locally while CI
is green (S-120, S-121, S-122).
Known
- Both supply-chain gates run upstream of
deploy, and this repository
deploys on every push todevelop. The trade is deliberate and both
documents now say so, but it means an unrelated upstream advisory can stop
every deployment. Decoupling it would mean a separateschedule:workflow;
continue-on-erroris not the answer, since it retires the gate rather than
moving it (CUI-0052, open).