Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
30 changes: 29 additions & 1 deletion scripts/pm/check-skill-line-ratchet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading