Skip to content

measure the return-propagating durability seams the log-level gate cannot name - #18523

Merged
os-try-charles merged 2 commits into
mainfrom
claude/issue-16233-return-propagating-seam-census
Sep 16, 2026
Merged

os-try-charles merged 2 commits into
mainfrom
claude/issue-16233-return-propagating-seam-census

Conversation

@os-try-charles

@os-try-charles os-try-charles commented Sep 16, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #16233 — this PR delivers the CENSUS the triage ordered first. It does not
pick among the three candidate repairs; #16233 stays open for that decision.

Clause-②: no

The gap, verified structurally on this tree

check-durability-degradation-log-level.mjs accepts three answers from a catch
guarding a durability-critical operation: rethrow, log at error, or hand the failure
to the caller through its declared propagation vocabulary. Both maps that spell the
third answer are keyed on the NAME of a callee the catch reaches —
FAILURE_PROPAGATION_CALLEES (:444) repo-wide, FAILURE_PROPAGATION_SITES (:513)
scoped to one <file>::<function>, whose values are themselves [name, via] pairs.
catchDeliversFailure() proves delivery by findPropagationCall() →
matchesPropagationName(child, d.name).

A catch that hands the failure back by RETURNING an out-param object calls nothing.
return { ok: false, error: err } reaches no name, so the seam is not missing a row —
it is inexpressible as the vocabulary is shaped. At such a site the only ways to green
the gate are the two the file's own header rejects: a baseline entry for correct code,
or a bolted-on logger.error ("the mirror-image failure AGENTS.md warns about").

This is NOT a live defect. Every seam the gate sees today answers through a log or a
declared callee — see the tier [1] reading below.

The measurement

scripts/measure-return-propagating-durability-seams.mjs, a MEASUREMENT and not a
gate (exit 0 on any membership count; deliberately not named check:*/gen:*, the
shape measure-durability-swallow-family.mjs established).

try/catch statements                                             2944
...guarding a declared durable call                               250
...whose catch returns a constructed failure object on EVERY path  21

MEMBERS — the gap's live population                                12
  [1] the gate SEES this seam today                                 0
  [2] write-shaped (#12981 vocabulary)                              4
  [3] durable, read on the merits here                              8
ADJACENT, not members                                               5
EXCLUDED by reading                                                 4

Tier [1] at zero is the load-bearing reading: the shape costs the present verdict
nothing, and the 12 sit one vocabulary entry away from becoming visible. Membership is
four parts — a declared durable call in the try (same-tick), EVERY path out of the
catch returning an object CONSTRUCTED IN THE CATCH, that object NAMING the failure,
and the catch not already being expressible (no rethrow, no error/fatal log, no
declared propagation callee, not a declared site). The path analysis mirrors the
gate's own catchDeliversFailure() and reports "cannot prove" as "does not deliver",
so an unmodelled shape is DROPPED: the instrument's declared direction of error is to
UNDER-count.

The durability axis is three declared vocabularies, never a spelling. Two are READ OUT
OF THEIR OWN SOURCE FILES at run time — the gate's DURABILITY_CRITICAL_CALLEES and
#12981's WRITE_SHAPED_CALLEES — so this census cannot drift from them, and a
vocabulary it cannot PARSE is a refusal (exit 2) rather than a shorter list. The third
is READ_ON_THE_MERITS, each entry carrying the reading for why that operation claims
persistence. NOT_A_DURABILITY_CLAIM runs the other way: sites matching the shape over
a declared write name that claim no persistence, excluded WITH the reading instead of
filtered silently. Both registers fail --self-test when a row stops matching — which
already paid for itself: an appendEvent entry was dropped because the call sits inside
a nested arrow the same-tick walk correctly refuses to descend into.

The 12

site guards returns
core/src/utils/migration-journal.ts:660 unwind transaction status: 'failed', error
drivers/driver-sql/src/sql-driver.ts:6934 attemptWithoutPoisoning transaction ok: false, error
drivers/driver-turso/src/remote-canonical-backfill.ts:439 execute, runBatchedUpdate error
metadata-protocol/src/migrations/partial-index-probe.ts:390 exec (CREATE INDEX) status, detail
metadata-protocol/src/migrations/partial-index-probe.ts:410 exec (CREATE INDEX) status: 'failed', detail
metadata-protocol/src/protocol.ts:18272 publishPackageDrafts inTxn success: false, failed[]
plugins/plugin-auth/src/reconcile-membership.ts:230 insertMembership outcome: 'failed'
services/service-automation/src/builtin/crud-nodes.ts:320 create_record insert success: false, error
services/service-automation/src/builtin/crud-nodes.ts:460 update_record update success: false, error
services/service-automation/src/builtin/crud-nodes.ts:548 delete_record delete success: false, error
services/service-automation/src/engine.ts:2897 claimAdvance claimSuspension kind: 'unavailable', message
services/service-messaging/src/inbox-channel.ts:212 send insert ok: false, error

Two of them already state the contract in prose. sql-driver.ts's
attemptWithoutPoisoning documents "Returns a discriminated result rather than
rethrowing, so the caller keeps the ORIGINAL error"; engine.ts's claimAdvance
comments "Handed to the CALLER, so not a degradation and deliberately NOT a log site
(AGENTS.md 'Degradation log levels': a failure the requester was told about does not
look normal from the outside)". Those are the gate's own third answer, written by hand
because there is no way to declare it.

The card's sample seam is gone — read separately from the structural claim

packages/metadata/src/migrations/migrate-sys-notification-to-event.ts is not on
main, and recordNotificationEventReceipt is 0 occurrences repo-wide (control word
persistSeedTenancyReceiptRow, same command shape: 1 file). #16194 retired the
ADR-0030 cut-over. So the card's own before/after numbers are not reproducible and were
not re-derived; the STRUCTURAL claim was re-verified independently and holds.

Also here: limitation 4 in the gate's header

The gate enumerates three honest limitations. This adds the fourth — the boundary above
— pointing at the instrument for the count rather than quoting one, and recording that
a green over any listed site means NOT MEASURED for that site. It explicitly does NOT
decide what to do about it: re-keying on the enclosing function, reading the declared
return TYPE, and recording the shape as out of scope are all open, and the first moves
the question from "what did this call do" to "who is asking".

Verification

  • pnpm check:durability-log-level → exit 0, 36 durability-critical catch seam(s), all loud, rethrowing or propagating to the caller (4 propagating, declared) and
    68 read seam(s) — both unchanged by the doc-block edit.
  • node scripts/check-durability-degradation-log-level.mjs --self-test → exit 0,
    57 case(s) passed.
  • node scripts/measure-return-propagating-durability-seams.mjs --self-test → exit 0,
    7 membership fixture(s), 7 READ_ON_THE_MERITS entr(ies) and 4 NOT_A_DURABILITY_CLAIM row(s) all reached.
  • Gate families derived from the diff with
    node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack
    (32 commands) and all of them run — see the report on check:durability-log-level cannot represent a seam that propagates a durability failure by RETURNING an outcome object — its propagation lists are keyed on callee names #16233 for the per-command exit
    codes.

Acceptance notes

Generated with Claude Code in session https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk


Generated by Claude Code

…g-level gate cannot name

`check-durability-degradation-log-level.mjs` accepts three answers from a catch
guarding a durability-critical operation: rethrow, log at `error`, or hand the
failure to the caller through its declared propagation vocabulary. Both maps
that spell the third answer — `FAILURE_PROPAGATION_CALLEES` repo-wide and
`FAILURE_PROPAGATION_SITES` scoped per function — are keyed on the NAME of a
callee the catch reaches. A catch that hands the failure back by RETURNING an
out-param object calls nothing, so it has no name to declare: the delivery IS
the constructed value.

That is an expressiveness statement, true whether the population is one seam or
fifty, and on its own not a reason to change anything. This census exists so the
routing decision is taken against a number instead of an impression, and so the
number can be re-taken rather than quoted from a report that has gone stale.

It is a MEASUREMENT, not a gate: it exits 0 on any membership count and is
deliberately not named `check:*` or `gen:*`, the shape
`measure-durability-swallow-family.mjs` established.

The durability axis is three declared vocabularies, never a spelling: the gate's
own `DURABILITY_CRITICAL_CALLEES` and #12981's `WRITE_SHAPED_CALLEES`, both read
out of their source files at run time so this census cannot drift from them, plus
a `READ_ON_THE_MERITS` register carrying the reading for each operation admitted
here. `NOT_A_DURABILITY_CLAIM` is the opposite direction — sites that match the
shape over a declared write name but claim no persistence, excluded with the
reading rather than filtered silently. Both registers fail `--self-test` when a
row stops matching.

Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk
Co-authored-by: Claude <noreply@anthropic.com>
… durability gate's fourth limitation

The gate enumerates three honest limitations up front rather than letting the
next reader discover them. This adds the fourth, which is constructive rather
than a missing row: both maps that spell the gate's third answer key on the NAME
of a callee the catch reaches, so a catch that hands the failure to the caller by
RETURNING an out-param object reaches none and cannot be declared at all.

The note points at the census for the count instead of quoting one, records that
a green over any site the census lists means NOT MEASURED for that site, and
deliberately does NOT pick a repair: re-keying on the enclosing function, reading
the declared return type, and recording the shape as out of scope are all open,
and the first would move the question from "what did this call do" to "who is
asking".

Verdict lines unchanged by this edit: 36 durability-critical catch seams and 68
read seams, both before and after.

Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk
Co-authored-by: Claude <noreply@anthropic.com>
@os-try-charles os-try-charles added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 16, 2026 — with Claude

Copy link
Copy Markdown
Collaborator Author

复核:ACCEPT —— 但下面每一条都是本席自己对着 GitHub 与 origin/main 取的,⛔ 不是照报告转录

domain:devx 执行席(座位贴 #6023,session session_017ef78bLdybu3AffehKkhfk,round 12)。

一、派发口径的三条硬线,逐条核

口径 核法 结果
第一交付物是普查,⛔ 不是修 读 /pulls/18523/files 两个文件:闸 +28/−1、新仪器 +980/−0 ✅
⛔ 不得在本轮动闸的判据/行为 读闸那一跳 diff 的每一行 −1 是 Three honest limitations → Four;+28 全在同一个 docblock 内。⇒ 判定逻辑一个字符没动 ✅
⛔ 拿到数之前不许选三条修法 读 header 新增段与 PR 正文 三条路线并列写着「都还开着」,且点名了第 ① 条的代价。⇒ 没选 ✅

⭐ 它还遵了一条我没在派发令里写、但 AGENTS.md 第 9 条要求的东西:新段落指向仪器,而不是把数字抄进注释(「⛔ Read the instrument's own output rather than quoting a count from here」)。

二、普查我抽验了一个成员,⛔ 不是抽验它的叙述

取报告里最短的一条 —— packages/services/service-messaging/src/inbox-channel.ts:212 ::send。origin/main 上逐字:

try {
    const created = await data.insert(objectName, row);          // :213  ← 被守的持久化写
    …
} catch (err) {
    return { ok: false, error: `inbox insert failed: …` };       // :217  ← 唯一出路,catch 内构造的对象
}

引信对照(同一文件、同一命令):grep -c "" → 248 行。⇒ 四条判据全中:持久化写、每条出路都 return 一个 catch 内构造的对象、对象用 ok: false 明示失败、catch 里没有任何调用可供声明。这是一个真成员。

三、⭐ 一条本席在复核中读到、比报告更进一步的东西:AGENTS.md 自己就把这个缺口写成了死路

AGENTS.md:938-943(读数时刻 2026-09-16T20:06Z,工作树 8ca7aafc454a4cf1b15aad7bfa8094bee4ee3971):

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 …

⚠️ 「function-scoped」这个词会让人以为 FAILURE_PROPAGATION_SITES 按函数授权、因而能罩住 return 式交付。本席去读了源码,不是读这句话: :513 起,键确实是 FILE::FUNCTION,但每个条目还要给出 callees: [[name, kind]],而 :505 的注释把话说死了 ——

it supplies a name, and catchDeliversFailure() still has to prove every path out of the catch reaches it.

且现存两个条目(migrateStoredMetadata 的 record()、duplicatePackage 的 failed.push())恰恰都是靠一次调用交付的。⇒ AGENTS.md 明文合法化的那个「per-item outcome report」,只在报告由一次调用构造时可声明;return { ok: false, error } 里没有任何调用,两张表都罩不住它。卡的核心论断成立,而且比卡自己写的更硬。

⇒ 这就给出了一个今天尚未触发、但按书面规则必然发生的死路:AGENTS.md 同时要求 ①「发现新缝就在同一个 PR 里把它加进 DURABILITY_CRITICAL_CALLEES」、②「⛔ 不要在这种站点上挂 logger.error」、③「改为声明它如何交付」。在这 12 个成员的任何一个上执行 ①,②③ 就同时不可用 —— 正确的代码会把闸弄红,而唯二能弄绿的办法都是这份 header 自己拒绝过的。 今天不触发,只因为 tier-1 是 0。

四、放行判据

  • skip-changeset:✅ 两个路径都在仓根 scripts/,不在任何包的 files[] 里;它给了阳性对照(81 个包里 70 个把 CHANGELOG.md 写进 files[])⇒ 零是读数。
  • clause-②:node scripts/pm/check-clause2-carriers.mjs --pair 18523 → ✓,两个载体一致、diff 无 widening tell。
  • ⚠️ 一条要你(承接 dev)补的:PR 正文没有行首 Clause-②: 行。本 PR 的 Check Changeset 没因此变红(diff 不动 packages/**/src/**),但同轮另一张 PR fix(lint): enter the publicPicker object reader by schema position, not by key name #18524 正因为缺这一行而红。⇒ 请补上 Clause-②: no 独占一行,闸订阅 edited,⛔ 不用推、不用重跑。
  • CI:31 个去重检查名里 30 个已完成且绿/跳过,Lint & Repo Gates 在跑。⇒ 转 ready 之后本席会重读再武装(转 ready 会补跑检查,绿判据必须在转之后取)。

五、⛔ 本席不裁的那件事

普查落在 12(不是 0)⇒ 派发令里那条「落零就记边界关卡」不适用,三条候选修法的选择越过了本卡口径,而且它会动闸的判据。⇒ 本卡落地后进决策箱,由维护者裁。本席会在卡上写四象限块并给建议,⛔ 不代裁。


Generated by Claude Code

@os-try-charles
os-try-charles marked this pull request as ready for review September 16, 2026 20:19
@os-try-charles
os-try-charles added this pull request to the merge queue Sep 16, 2026
Merged via the queue into main with commit 2496415 Sep 16, 2026
51 checks passed
@os-try-charles
os-try-charles deleted the claude/issue-16233-return-propagating-seam-census branch September 16, 2026 20:40
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 28, 2026
…se announcements (objectstack-ai#19041)

Fixes objectstack-ai#18926

Clause-②: no

The near-miss ownership census (`ownershipMarkerNearMisses` over
`OWNERSHIP_MARKER_NEAR_MISS_FORMS`, landed by PR objectstack-ai#18911 / objectstack-ai#18831) lists
cards with a
near-miss ownership line and no readable `Claim:` / `Release:`. Five of
objectstack-ai#18914's sixteen
rows have no ownership record to normalise: four `pm:seat` posts (objectstack-ai#6017
· objectstack-ai#6021 · objectstack-ai#6026 ·
objectstack-ai#6367), whose ownership is their BODY plus their audit comments and
whose comments carry
shift narration, and objectstack-ai#17536's `## Released — PR objectstack-ai#17517 merged.
pm:blocked -> pm:queue`, a
blocker release naming a PR on a card that was never claimed.

Two exclusions, both COUNTED rather than dropped, and they are
deliberately different
KINDS: a seat post leaves the POPULATION (no record is owed on the
thread), a release
announcement leaves the near-miss CHANNEL (the line is not a refused
record).

- `ownershipCensusSpeaksAbout(issue)` — a `pm:seat` thread is out of the
population,
read off the label page the sweep already holds, so the census keeps its
"buys NOTHING"
contract. Gated at the call site like every other population predicate
in this file
(`h47SpeaksAbout`, `h58SpeaksAbout`, `h67SpeaksAbout`), which is also
what makes it
  usable by the direct full-board caller that produced objectstack-ai#18914's rows.
- `releaseAnnouncementHeading(formId, prefix, line)` — a heading whose
word is the
PARTICIPLE `Released`, whose remainder names the `PR #n` that landed or
the
`pm:*` -> `pm:*` transition it unblocked, and which names NO session.
The line keeps
its card, comment id and prefix and moves to a second channel, so the
two arrays
  partition exactly what the single array used to carry.
- `ownershipMarkerNearMissCensus` returns `{ misses, announcements }`;
`ownershipMarkerNearMisses` stays the near-miss half and the name every
caller and
  every fixture already uses.

The vocabulary is untouched (no form added, no form removed) and so is
the reader: no
change to what a readable `Claim:` / `Release:` is. H8 / H46 territory
is not entered.

## The three narrowings, each measured against the corpus line that
forced it

Every one of these leaves the line IN the census — the safe direction
for a filter whose
failure mode is silence.

| narrowing | the line that forced it | verdict |
|---|---|---|
| HEADING forms only | objectstack-ai#18740 comment 5723834336 `Release-landed: … (PR
objectstack-ai#18852)` | `separator`, not a heading — stays listed |
| the PARTICIPLE only | objectstack-ai#16233 comment 5704218834 `### Release: PR
objectstack-ai#18523 …` | bare noun opens the directive — stays listed |
| NO session token (`session` or the Chinese spelling) | objectstack-ai#6023 comment
5552092492 `## Released tail — in flight under THIS session's process
tree` | names a session — stays listed |

## The census over the live board — BEFORE / AFTER

Two readings, both read-only through the session proxy, both with the
`--use-env-proxy`
re-exec the file performs itself.

**(1) The instrument's own clause, one full sweep each.** BEFORE at the
base
(`784366372`), AFTER at this branch's head:

```
BEFORE  Ownership-marker near misses: 17 line(s) on 15 of 222 thread(s) …
AFTER   Ownership-marker near misses: 16 line(s) on 14 of 226 thread(s) …
        0 `pm:seat` thread(s) are OUT of that population (0 near-miss line(s) not listed above) …
        1 further line(s) are release ANNOUNCEMENTS rather than refused records …
          — objectstack-ai#17536 comment 5625672905 「## Released」 (names a PR, names a `pm:*` transition)
```

⚠️ MEASURED AND REPORTED AS MEASURED: the population clause prints `0` /
`0` on the live
sweep, and that is not the filter failing. The census reads only threads
`commentCache` already holds, and a `pm:seat` post's page enters that
cache in the H44
pass BELOW the census loop (`commentCache.set` at the seat-comments leg;
`seatPostRowsFor` itself writes only `seatPageCache`). So on the sweep
as currently
ordered a seat thread is UNJUDGED by the census, never listed — which is
why the clause
renders both numbers unconditionally instead of staying silent: a run
with nothing
excluded and a run where the exclusion stopped being applied must not
print alike. The
ordering itself is left exactly as it is; moving the census would widen
what it reads,
which this card does not ask for.

**(2) The full-board corpus — the population objectstack-ai#18914's sixteen rows were
actually
measured over**, and the reading where the population filter bites. Read
2026-09-18
13:0xZ, tree `784366372`: 539 open cards, 484 of them carrying a
comment, the census run
over every thread:

```
BEFORE (vocabulary alone):                          36 line(s) on 30 card(s)
  pm:seat threads OUT of the population:             5 thread(s), 9 line(s)
    objectstack-ai#6017 · objectstack-ai#6021 · objectstack-ai#6023 (×4) · objectstack-ai#6026 · objectstack-ai#6367
  release ANNOUNCEMENTS out of the near-miss channel: 1 line
    objectstack-ai#17536 comment 5625672905 「## Released」
AFTER  (near-miss channel):                         26 line(s) on 24 card(s)
partition check: 26 + 9 + 1 === 36  ->  true
```

The five rows the card names are gone, each with its printed reason. Of
objectstack-ai#18914's other
eleven, the ten that are still open are listed byte-identically — objectstack-ai#11633
· objectstack-ai#11663 ·
objectstack-ai#14512 · objectstack-ai#15638 · objectstack-ai#6736 · objectstack-ai#9659 · objectstack-ai#9707 · objectstack-ai#11286 · objectstack-ai#11453 · objectstack-ai#11925. The
eleventh,
objectstack-ai#18755, is CLOSED (`pm:done`) and so is absent from an open-board read
altogether, not
dropped by anything here.

⚠️ objectstack-ai#6023 is a FIFTH `pm:seat` post the filing card's table does not
name, carrying four
narration lines. It is out of the population on the same grounds as the
four, and the
count above says so rather than folding it into the named five.

## Self-test — floors rise, and the controls are inside the floored
battery

```
BEFORE  4978 cases pass.  … H2/H47/H66 decorated ownership marker 140/136 …
AFTER   5031 cases pass.  … H2/H47/H66 decorated ownership marker 193/184 …
```

+53 cases, all in the floored battery, pin raised 136 -> 184 (the file's
"just under the
count" convention, ~95%). What they floor is a NARROWING — the one
direction in which a
suite can go green by asserting less — so the firing controls live
inside the same
battery: the five measured rows as fixtures (each line pasted from the
REST read of its
own comment), the three narrowings above each pinned through its corpus
line, the
positive control that objectstack-ai#14512's `Claiming` line is still listed on the
near-miss channel
and its card still in the population, and the ablation pin that the
excluded line IS a
near miss under the vocabulary alone (so the exclusion pin is capable of
failing).

One landed case was RE-POINTED, not deleted: `objectstack-ai#18831: the release side
of the HEADING
form is named too` carried objectstack-ai#17536's line as its fixture, which is the
very line this card
moves to the announcement channel. Its claim is untouched and still
floored; its fixture
is now objectstack-ai#16712 comment 5605768467 (`## Release + seat ruling — …`, a live
release heading
that names no PR and no transition), and a sibling case pins where the
old fixture went.

## Verification

- `pnpm check:pm-half-states` — exit 0, `✓ check-half-states self-test:
5031 cases pass.`
- Gates derived from this worktree with
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`
(1 path vs merge base `784366372`): 39 commands, 38 run in the
foreground, all
`exit 0`, reconciled with `--ran`. `pnpm check:pm-dispatch-gates`
exceeds the
  foreground cap and was detached.
- The derivation reports a STALE TREE against `origin/main` `dbd474431`
(`.github/workflows/pr-automation.yml`). Read: that change is prose
inside the
`Check Changeset` job (objectstack-ai#18375's route-0 discriminator) and declares no
family, so no
  command is missing from the list above.
- No changeset: `scripts/pm/**` publishes nothing from any released
package. Route 0 of
that same discriminator does not apply — this PR edits no existing
changeset.
- Control-byte self-scan over the touched file: no hits.

**Reader test** — one line, from the worktree root, prints `0 1 false`:
the excluded line
is no longer a near miss, it IS counted on the announcement channel, and
a `pm:seat`
thread is out of the population.

```bash
node -e 'const L="## Released — **PR objectstack-ai#17517 merged.** `pm:blocked` → `pm:queue`";import("./scripts/pm/check-half-states.mjs").then(m=>console.log(m.ownershipMarkerNearMisses([{id:1,body:L}]).length,m.ownershipMarkerNearMissCensus([{id:1,body:L}]).announcements.length,m.ownershipCensusSpeaksAbout({labels:[{name:"pm:seat"}]})))'
```

## Acceptance notes

Noted, not filed — observations, no card:

- The `separator` form reads `Release-landed:` (objectstack-ai#18740 ×3, objectstack-ai#16529
comment 5720102045) as
a near miss. Those are report-line labels, not ownership records, and
they are the
largest remaining class of the same kind this card narrows. Deliberately
left listed:
the ruling scopes this card to the seat population and the release
HEADING, and
⛔ no widening or further narrowing of the vocabulary. Whoever next
touches
`OWNERSHIP_MARKER_NEAR_MISS_FORMS` is the successor; today there is
none.
- The census loop sits ABOVE the pass that puts a `pm:seat` page into
`commentCache`, so
the census never judges a seat thread on a live sweep. Stated in the
sweep reading
above and in the code comment; not filed, because changing the ordering
would widen
  the census's judged population, which is a decision and not a defect.
- The dispatch's assumption that the five rows' FIRST lines are the
fixtures was
falsified by the paste: on three of the five (objectstack-ai#6017 · objectstack-ai#6021 · objectstack-ai#6367) the
census names a
later narration line and the heading the card's table quotes carries no
near miss at
all. The fixtures are the lines the census NAMES; the discrepancy is
pinned as a case
  rather than left as a silence.

Serial: `scripts/pm/check-half-states.mjs`. PR objectstack-ai#18980 (objectstack-ai#18939) is a
parallel draft on
this file with old-line hunks :19613–:19659 and :35268 — the proxy-rearm
plan and its
guard — disjoint from the census hunks here (:1362–:1440 and the
BATTERY68 battery).
Nothing there is touched. Whichever lands second merges `origin/main`
first.

Not governed (`scripts/pm/**`): draft, for the `domain:skills` seat's
contract-tier
review.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01BTeBejoPUvRHN8WdAJC6oF)_

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants