diff --git a/AGENTS.md b/AGENTS.md index fa8f80a8758..cc3cea27686 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -931,16 +931,26 @@ restores durability, or the explicit opt-out that makes the degradation delibera (`suspendedRunStore: 'memory'`, `OS_SKIP_SCHEMA_SYNC`). Say it **once**, at the first degradation, not once per failed write. -**Do not over-apply it.** Escalating a functional degradation to `error` trains -everyone to skim `error`. An `if (!service)` composition branch is usually functional -and belongs at `warn`; a `catch` around a write, a DDL call, or a store initialization -is where this rule bites. **And a failure handed to the CALLER is not a degradation at -all** — the third legal answer: a `catch` that answers `errorFromThrown(e, 400)`, or a -batch whose contract IS a per-item outcome report, does not look normal from the -outside — the requester was told. Do **not** bolt a `logger.error` onto such a site; -declare **how it delivers** instead — `FAILURE_PROPAGATION_CALLEES` (repo-wide names) -or the function-scoped `FAILURE_PROPAGATION_SITES` in the checker, which then proves -structurally that *every* path out of the `catch` delivers. +**Do not over-apply it.** Escalating a functional degradation to `error` trains everyone +to skim `error`. An `if (!service)` composition branch is usually functional and belongs +at `warn`; a `catch` around a write, a DDL call, or a store initialization is where this +rule bites. **And a failure handed to the CALLER is not a degradation at all** — the +third legal answer: a `catch` that answers `errorFromThrown(e, 400)`, or a batch whose +contract IS a per-item outcome report, does not look normal from the outside — the +requester was told. Do **not** bolt a `logger.error` onto such a site; declare **how it +delivers** instead — and which declaration exists depends on how the failure leaves the +`catch`. Delivered by CALLING something: name that callee, repo-wide in +`FAILURE_PROPAGATION_CALLEES` or function-scoped in `FAILURE_PROPAGATION_SITES`, and the +checker then proves structurally that *every* path out of the `catch` reaches it. +Delivered by **RETURNING** an outcome object — `return { ok: false, error }`, a `failed` +receipt — there is **no callee to declare**: the delivery IS the constructed value, and +both maps key on a name. ⛔ Never add such a seam to `DURABILITY_CRITICAL_CALLEES` or to +either `FAILURE_PROPAGATION_*` map, ⛔ never baseline it, ⛔ never bolt on a +`logger.error` to green the checker: the shape is outside its reach by construction. Pin +it in **its own file's test** asserting the returned failure outcome (the +`failed`-receipt case is the reference shape), and read its population from +`scripts/measure-return-propagating-durability-seams.mjs`. ⭐ The invariant does not +move: silent data loss must be loud, so what this checker cannot see, that test holds. **It has teeth**: `pnpm check:durability-log-level` (`scripts/check-durability-degradation-log-level.mjs`; its header is the authority) diff --git a/scripts/pm/check-skill-line-ratchet.mjs b/scripts/pm/check-skill-line-ratchet.mjs index 8d3288863b7..d78ac4eb18a 100644 --- a/scripts/pm/check-skill-line-ratchet.mjs +++ b/scripts/pm/check-skill-line-ratchet.mjs @@ -1435,7 +1435,35 @@ export const CEILINGS = new Map([ // 并按实测行数抬上限」; recorded by the director on #15410 comment 5682595374, which // also refuses option D). AGENTS.md is not a CROSS_FILE_MOVES destination, so no // `ruledRaises` record applies. Landed count, headroom 0, same convention. - ['AGENTS.md', 1099], + // + // 1099 → 1109 (card #16233): § Degradation log levels' third-legal-answer + // paragraph brought to the instrument, per letter C — a `catch` that delivers by + // RETURNING an outcome object (`return { ok: false, error }`, a `failed` receipt) + // has no callee to declare, so it is ⛔ never added to + // `DURABILITY_CRITICAL_CALLEES` or to either `FAILURE_PROPAGATION_*` map, + // ⛔ never baselined and ⛔ never log-bolted to green the checker; it is pinned by + // its own file's test and its population read from + // `scripts/measure-return-propagating-durability-seams.mjs`. Until this line the + // text prescribed, for all 12 censused seams, the two remedies the gate's own + // header refuses — correct code reds the gate, and the only two ways to green it + // were the two it forbids. +10 lines, measured: the paragraph goes 10 → 20 + // physical lines and the file 1099 → 1109, and it is bought by CONTENT, not by + // bad wrapping. Re-measured on the merged tree with this gate's own `wrapLine`, + // at the width the section is actually typeset at (median 85 B, p90 89 B, max + // 90 B — inside the ≤91-byte ASCII-prose convention the 120-byte cap above + // codifies): a greedy rewrap returns exactly the 20 lines the paragraph already + // occupies at 90 B, and 21 at 88 B ⇒ 0 lossless-rewrap headroom. Lines come back + // only by re-typesetting ASCII prose ABOVE that convention (18 at 100 B, 15 at + // 120 B; the whole section 88 → 69 at 120 B), which is the reflow that cap + // documents itself as NOT imposing — and re-wrap funding is refused per the + // 2026-08-17 rule in any case. Maintainer ruling, verbatim and untranslated: + // 「1. #19214 / 卡 #16233 —— AGENTS.md 行预算, A 批 +10(1099→1109)」 + // — the maintainer's live instruction to `session_019srGWGCBBCBHqcDoRZpQRh`, + // recorded on #16233 comment 5750261694; it rules the line budget that the + // standing letter-C ruling 5716260390 left unruled when it named the text. + // AGENTS.md is not a CROSS_FILE_MOVES destination, so no `ruledRaises` record + // applies. Landed count, headroom 0, same convention. + ['AGENTS.md', 1109], // #9965: root CLAUDE.md is the other repo-root instruction file — same read // path (every seat session), same governance (Prime Directive #14). It is // structurally growth-prone in the way the ratchet is built for: it exists to