Commit Graph

16 Commits

Author SHA1 Message Date
iomgaa 503c06327e feat: let the retention script be told which table it may delete from
Until now the target came from whatever search_path resolved to. The
script printed what it found, but that print and the DELETE happen in
the same run with nobody in between, so it only ever helped the person
who ran a dry-run first. Swap the role that runs it and "$user" can
resolve somewhere else entirely.

--table takes the whole qualified name and resolves it directly. The
table half has to be llm_calls: a version that accepts any name turns
one typo into a general purpose row deleter, and any table with a
created_at and a tenant_id would go through the same batched DELETE
without complaint.

The tests that run it now run as a role that owns its own scratch table
and holds nothing on the shared one, so the row-count snapshot could
go. What replaced it is a case that lets the script fall through to the
shared table on purpose and asserts it exits 2 having deleted nothing.
That one has no red-first path, since making it red means running it as
the superuser, which is the thing being prevented; the finding's probe
covers it instead.

Five of the new usage tests passed before the flag existed, because
argparse rejects an unknown --table with exit 1 and the word --table in
stderr, which is exactly what they asserted. They now also assert the
error is not "unrecognized", which is the difference between testing
the validation and testing argparse.
2026-08-26 10:38:21 -04:00
iomgaa 4b06093d6c refactor: split the retention arg checks per backend
_validate carried the whole matrix in one function (cc C/13, over the
branch quality gate). Splitting it by what is actually being checked —
shared, sqlite-only, postgres-only — puts every piece at A/B.

Ordering is the part that had to survive: the chain's order is the error
messages' priority, so a run with several bad flags still reports the
same one it did before. The --vacuum/--apply pairing therefore stays in
the shared step ahead of the backend branch, where it was; it is a "do
not rewrite the whole file when you only meant to look" rule, which
holds before the question of which backend a flag belongs to.

No behavior change: all nine parser.error strings are byte-identical and
in the same order, and the eight usage-error cases pass unmodified.
2026-08-19 15:19:35 -04:00
iomgaa 511aa4899c feat: add a retention script downstreams can schedule
The library only ever SELECTs/INSERTs into llm_calls (D15), so expiring
rows has to live outside it — holding DELETE would contradict the
REVOKE UPDATE, DELETE the deployment template recommends.

tools/telemetry_retention.py is dry-run by default and prints the row
count, the created_at window and the tenant_id spread so an operator can
tell whether the rows about to go are the intended ones. The Postgres
branch refuses partitioned targets with exit code 3 (DETACH/DROP
PARTITION is O(1); DELETE is not) and otherwise deletes in per-batch
transactions. Missing asyncpg exits 2 rather than degrading quietly:
this is an ops tool, and a silent "0 rows" reads as "already clean".

Exit codes are the contract with the scheduler, so argparse errors were
moved off 2 (now 1) to keep "bad flags" distinguishable from "cannot
reach the database".

The Postgres cases run against the real instance in throwaway schemas —
never public.llm_calls — and the batch case asserts the shared table's
row count is unchanged, so a search_path that failed to apply lands as a
red test instead of a deletion.
2026-08-19 14:11:22 -04:00
iomgaa e949edb62a feat: gate the automatic ALTER behind an explicit mode
两个 recorder 的 `__init__` 增 keyword-only 必填 `auto_migrate`(设计 D-c:
缺省规则只写在 config 一处,不与类签名漂移),并把写入语句从模块级常量改为
实例级: manual 档探测到旧表缺列时一条 ALTER 都不发,改按现有列裁剪 INSERT,
准备期发一次 warning(逐列点名 + "以下维度不会被记录" + 可直接执行的补列 SQL)。

裁剪是关掉 ALTER 的前提而非增强: 旧表缺列时若既不 ALTER 又不裁剪,每一行
INSERT 都撞 `no column named tenant_id` 被整行丢弃,比自动 ALTER 更严重地
违反"遥测必录"。auto 档行为逐字不变(先探测后 ALTER、duplicate column 视为
成功、失败只 warning 不判死、写入沿用全量列)。

探测失败、或探测结果与 COLUMNS 毫无交集,两档都保守回落全量列——空列集会让
`insert_sql` 产出 `INSERT INTO llm_calls () VALUES ()`(它不拒空列表,空集
技术上是子集)。PG 侧 `_columns`/`_insert` 与 `_schema_ready` 在同一处一起
赋值,不留"已就绪但语句还是旧的"窗口。

同批改 `GatewaySettings.telemetry_auto_migrate`(按后端派生: PG False、
SQLite True)与 `client._build_telemetry` 透传: 签名变更与其唯一调用点必须
落在同一次提交,否则该提交点整条装配路 TypeError。env 键留给下一步。
2026-08-19 11:57:41 -04:00
iomgaa acc419a29b chore: add a mechanical wiki-vs-source alignment checker
七轮人工审查的 88 条发现里,签名/导出/字段序/列数/env 键这几类是机械可
比对的,不该靠人一轮轮追。五项检查全部由源码反推,已用注入历史错误的方式
验证有效: gather_bounded(coros, limit)、source_name 排进前 11 位、列数写
成 20、EXTRA_BODY 漏文档 —— 四条全部命中。

不并入 make ci: wiki 是独立仓库,仓库里没有它时自动跳过等于静默降级(违
P5),故做成显式的 make wiki-check WIKI=<path>。
2026-08-02 02:16:16 -04:00
iomgaa 3c9f306ea3 fix: address M3 verifier findings on soak invariants and probe tests 2026-07-22 02:21:33 -04:00
iomgaa bb1600c0f1 feat: add P7 OCR soak scenario and scoreboard 2026-07-21 23:22:12 -04:00
iomgaa 0e0d599441 chore: print per-source reason chain on soak call failure 2026-07-21 14:37:49 -04:00
iomgaa 5dfd88c4d6 fix: make RPM jitter exemption side-aware with one-shot room
Verifier adversarial cases showed pooled-room exemption could hide real
breaches: edge rows may only borrow from the neighbor on their own side,
and neighbor room is consumed globally so two windows cannot claim the
same slot. Also parse SQLite created_at as UTC, guard the dispatch
semaphore on progress-callback failure, and print a caveat that rescore
live checks reflect current db3 state.
2026-07-21 07:42:54 -04:00
iomgaa 56defc88fb fix: align soak scoreboard metrics with limiter semantics
RPM invariant now buckets by admit time on the Redis server clock,
exempts +/-2s boundary jitter, and excludes cache-hit rows that never
consumed a limiter slot. RSS sampling reports current ps RSS instead of
the monotonic ru_maxrss peak. Dispatch is paced by the concurrency
semaphore so --max-hours stays live and memory stays bounded. Add
--rescore RUN_ID to re-judge a finished run offline.
2026-07-21 07:22:34 -04:00
iomgaa ab9e3d10b2 fix: count terminal failure rows in soak telemetry tolerance 2026-07-21 04:40:06 -04:00
iomgaa aecc5fa216 fix: assert global error presence for fault-mixed soak scenarios 2026-07-21 04:22:04 -04:00
iomgaa 326dd24dd1 fix: address M2 verifier findings in soak harness 2026-07-21 02:05:49 -04:00
iomgaa 724dc3c328 docs: backfill env template and migration notes for M2 2026-07-21 01:28:33 -04:00
iomgaa 9aa97a61ae feat: add soak runner with budget guards and invariant scoreboard 2026-07-21 01:23:40 -04:00
iomgaa cca7071dbd feat: add soak corpus loaders and scenario generators 2026-07-21 01:17:46 -04:00