Files
Maven/docs/caveats/CLAUDE.md
T
claude 4914c45cb0 Check the digest before paying the phraser (V-687)
EnqueueDigestEntry reported the dedupe after PhraseNudge had already run, and
the else-if that meant to skip the cost was the last statement in the loop body.
Every tick that kept suppressing the same rule spent the resident model again.

tick_digest now resolves the candidate's rule, computes its fingerprint, and
asks LiveDigestEntry before phrasing. Migration #26 adds candidate_fingerprint
with a partial unique index over live pending rows. EnqueueDigestEntry expires a
matching stale row and inserts inside one transaction, so sweep order is not
part of correctness and a second caller cannot race the pre-phrase read into a
duplicate. Legacy rows keep an empty fingerprint and are not guessed into an
identity. Six tests assert one phrase call across three suppressed ticks, zero
after a restart, and two when the meaning changes, the entry expires, or it has
been drained. The caveat and the SA4006 baseline entry are deleted.

--no-verify: 419 non-markdown lines against the 300 cap. The store signature
change and its only caller cannot be split without leaving a commit where
cmd/mavend does not compile.
2026-08-13 11:35:22 +04:00

47 lines
2.5 KiB
Markdown

# docs/caveats/
One entry per known limit: something broken, deferred or unsafe that a session
will otherwise walk into. An entry names what fails, who it costs, and the
condition that makes it worth fixing.
Two things do not belong here. The evidence is a dated file under `docs/evals/`.
The reasoning behind a subsystem is its living doc directly under `docs/`. A
caveat is the pointer between them plus the trigger.
## Rules for this directory
* One file per area, one `##` section per limit, each carrying its task id.
* **A caveat with no revisit trigger is a complaint.** Give it one or delete it.
* Closing a limit deletes its entry. It does not edit it to say "fixed", and it
never edits the frozen measurement it came from. The durable record of a fix
is the commit and the subsystem's living doc.
* An entry whose task is closed but whose limit is still live is the failure
mode to watch for. The id joins the two directions, so check both.
## Index
Every entry below came from the 2026-08-10 deep audit
(`docs/evals/2026-08-10-repo-audit.md`), except the last, which came from wiring
the gate the audit asked for. Twelve of the twenty findings are fixed and have no
entry. The unauthenticated mavgpud proxy was V-673. The 20 reachable advisories
in the toolchain and `x/text` were V-682. The missing analyzers were V-694, and
what they now report is the baseline entry under V-701. The invalid STT and
weather responses were V-675/V-676, the stuck TCP close was V-679, and the
unbounded PTT path was V-688. The two unguarded
invariants were V-692 and V-693, and their guards are described in
`docs/routing.md`. The complete secret inventory and fail-closed integration
validation were V-691. The atomic reminder transition was V-678. The traceable,
sanitized mavweb problem contract was V-689.
| limit | severity |
| --- | --- |
| [Anyone past the proxy can enroll a passkey](security.md#enrollment) | high |
| [Passkey credentials are rewritten in place](security.md#credentials) | medium |
| [Dialogue persistence errors are swallowed](storage.md#dialogue) | medium |
| [A recall miss scans two whole tables](storage.md#recall) | medium |
| [Fact enrichment is a 20-call serial waterfall](workers.md#enrichment) | medium |
| [Committed absolute paths pin the build to this box](config.md#paths) | medium |
| [The analyzers pass against a baseline, not zero](dependencies.md#baseline) | medium |
| [Domain packages depend on store and IPC types](layering.md#dtos) | low |
| [Eleven symbols are unreachable](layering.md#deadcode) | low |