From c509364b08726c01d86bfc985b4aad303372976f Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 15 Sep 2026 04:14:38 +0000 Subject: [PATCH] fix(pm): H64 keys on the session id in the text, not on the author account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit H64's premise — MCP writes are user-authored, REST-proxy writes are `claude[bot]` — was superseded by the rule that write identity follows the channel and `user.login` records the token, not the seat. The row fired on compliant REST writes from user-token sessions, told their authors they had used the MCP tool, and prescribed a re-post through the REST proxy that lands under the same login — an unsatisfiable row re-filing every sweep against a trimmed anchor budget. Measured before re-keying: `performed_via_github_app` reads `{ id: 1236702, slug: 'claude' }` for a REST-proxy comment authored `claude[bot]`, for a REST-proxy comment authored by a user token, and for all four 2026-09-13 specimens. The field names the App whose credential signed the write, never the tool, so the channel cannot be read from a row at all. So the finding is now a seat/dev-signed artefact carrying no `session_` id anywhere — the attribution the landed rule requires — and its remedy is an edit that gives the artefact its id. The suspension exposure of a user-authored artefact is not relaxed: it is reported as an informational count plus a login roster in the summary clause, on every run, with no remedy named and no row filed, because no act available to a user-token session can clear it. Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr Co-authored-by: Claude --- scripts/pm/check-half-states.mjs | 771 ++++++++++++++++++++----------- 1 file changed, 505 insertions(+), 266 deletions(-) diff --git a/scripts/pm/check-half-states.mjs b/scripts/pm/check-half-states.mjs index dca4e1dbff5..ac93c610dc3 100644 --- a/scripts/pm/check-half-states.mjs +++ b/scripts/pm/check-half-states.mjs @@ -14224,28 +14224,70 @@ export function h63StaleFindingBesideGrade(issue) { } // --------------------------------------------------------------------------- -// H64 (#18069) — a seat- or dev-signed artefact whose GitHub AUTHOR is a user -// account rather than the App. +// H64 (#18069, re-keyed by #18237) — a seat- or dev-signed artefact that names +// no session. // // ## The defect, and why it is a half-state rather than a style note // -// Every agent on this board shares one protocol identity, and that identity has -// two spellings on the API. Content written through the MCP GitHub tools is -// authored by a USER account; content written through the REST proxy is -// authored by `claude[bot]`, whose `user.type` is `Bot`. Measured 2026-09-13 on -// this board: #18045 and objectui#9404 authored `os-project-manager` with -// bodies signed by the skills seat, PR #18051 authored `os-project-manager` -// with a dev-signed body, comment 5652138683 on objectui#9370 authored -// `os-tesla`; and comments 5654046782 / 5654227341 / 5654347747 authored -// `claude[bot]` as the clean side of the same pair. -// -// The two spellings are not interchangeable, and the inequality is the -// half-state: a SUSPENDED user account hides everything that account authored. -// The card, the claim and the report stay in the database and leave every -// reader's view at once — so a seat's own record of what it did is held by an -// account the protocol does not control. The artefact says a seat wrote it, -// GitHub says a person did, and the two carriers disagree about one live -// artefact with the repair on the board. That is `state`'s definition exactly. +// Every agent on this board shares one protocol identity, so an artefact's +// GitHub author cannot say WHO wrote it. The protocol answers that with the +// TEXT: 「`user.login` 记令牌不记席位,归属 = 文本里的 session ID」 +// (`.claude/skills/pm-dispatch/SKILL.md`), and the write identity follows the +// CHANNEL rather than the account — 「REST 按会话为 `claude[bot]` 或用户,MCP +// 恒用户」 (`.claude/skills/pm-dispatch/references/rest-channel.md`). +// +// So the half-state is an artefact whose text asserts seat/dev provenance — +// a claim, a report, a contract review, a filing header — while carrying no +// `session_…` id anywhere. The text says a seat or a dev wrote it; nothing in +// it says WHICH, and the author field records only the token that session was +// handed. Two carriers disagree about one live artefact and the repair is on +// the board: that is `state`'s definition exactly, and the repair is one an +// owner can actually perform — it gives the artefact its id. +// +// ## The premise this row was BUILT on, and the measurement that retired it +// +// ⚠️ Read this before proposing an author test again. The row originally read +// 「content written through the MCP GitHub tools is authored by a USER account; +// content written through the REST proxy is authored by `claude[bot]`」 and +// fired on `user.type !== 'Bot'`. Both halves are false as the rule landed, and +// the field this row used to tell the channels apart cannot tell them apart: +// +// `performed_via_github_app`, measured 2026-09-15 on live rows +// comment 5673548571 `claude[bot]` · `Bot` · `{ id: 1236702, slug: 'claude' }` +// comment 5673265919 `os-warren` · `User` · `{ id: 1236702, slug: 'claude' }` +// comment 5673413139 `os-warren` · `User` · `{ id: 1236702, slug: 'claude' }` +// and the four 2026-09-13 specimens this row was built from read the same +// slug (#18045, objectui#9404, PR #18051, comment 5652138683). +// +// The first two are both REST-proxy writes and differ only in the TOKEN CLASS +// the session was handed. The field names the APP whose credential signed the +// write; it never names the TOOL. ⛔ So no channel is inferred from it here, +// and an MCP-tool write is indistinguishable from a REST-proxy write in this +// payload. What the field still separates is an App credential from none: an +// absent slug is a user PAT, outside the App entirely. +// +// The retired test was not merely imprecise — it was unsatisfiable. It fired on +// REST writes the landed rule endorses, told their author the write 「went +// through the MCP GitHub tool channel」, and prescribed 「re-post it through the +// REST proxy」; for a session whose REST token IS a user account the re-post +// lands under the same login and the row fires again. A row that cannot be +// cleared re-files every sweep and competes for the anchor's trimmed budget +// with rows that can (441 half-states, 423 rows trimmed, 2026-09-14T19:41Z). +// +// ## The exposure is NOT relaxed — it is reported where it costs nothing +// +// A SUSPENDED user account hides everything that account authored: the card, +// the claim and the report stay in the database and leave every reader's view +// at once. That is measured on this board, not hypothetical — a previous +// account was suspended mid-shift and every comment and card it authored went +// 404 for every reader while labels and states survived intact. +// +// ⛔ Nothing here relaxes it. It is reported as an INFORMATIONAL count plus a +// login roster in the summary clause, on every run, and files NO row — because +// the token class is handed to a session at start rather than chosen at write +// time, so no act available to a user-token session moves its content to the +// App. A row naming no remedy that a reader could perform is the unclearable +// shape above; the clause states the exposure without spending the cap on it. // // ## The artefact is recognised STRUCTURALLY — ⛔ and never from a roster // @@ -14257,9 +14299,10 @@ export function h63StaleFindingBesideGrade(issue) { // authorship. ⚠️ The direction is what makes the two rows agree rather than // collide: H44 refused an author test for FINDING seat artefacts and that // refusal stands — this row finds them exactly the structural way H44, H33, H34 -// and H37 do, and reads the author only as the DEFECT, never as the way in. +// and H37 do, and since the re-keying it does not read the author as the defect +// at all. // -// ## The six signature forms, and the TWO the measurement widened +// ## The six signature forms, and the TWO that can never fire // // Four forms reuse a marker this file already owns, so 「what is a claim」 has // one answer here and not two: `CLAIM_COMMENT_MARKER`, `OS_DEV_REPORT_MARKER`, @@ -14267,6 +14310,13 @@ export function h63StaleFindingBesideGrade(issue) { // `directiveValues`' decoration contract. Two are this row's own: the filing // header, and a session id. // +// ⚠️ Two of the six ARE session ids — the bare id in the head window and the +// attribution footer's `claude.ai/code/session_…`. A text matching either +// carries an id by construction and can therefore never fire; the finding +// population is the other four forms with no id ANYWHERE in the body. That is +// not a gap: those two forms exist so the row can SEE an artefact as seat/dev +// content, and seeing it attributed is the clean reading. +// // ⚠️ Two of the filing card's five forms were MEASURED against the specimens it // named and would not reach them. Both widenings are recorded here because a // reader comparing the card to the code must see the reason, not a drift: @@ -14277,6 +14327,10 @@ export function h63StaleFindingBesideGrade(issue) { // line anywhere in its 35 lines. Requiring the line excludes // the specimen, so the form is `CLAIM_COMMENT_MARKER` alone, // which is also the marker every other claim reader here uses. +// Under the re-keying that specimen is this row's live +// positive: it names its seat by ACCOUNT (`os-tesla`) and no +// session at all, which is precisely what the landed rule +// says cannot carry attribution. // the session form the card wrote 「a bare session id in the first three // lines」. PR #18051 — the card's own dev-signed fixture — // carries its ONLY session token on line 45 of 45, in the @@ -14292,51 +14346,45 @@ export function h63StaleFindingBesideGrade(issue) { // signature: the platform appends it to comments, so reading // it would make the row fire on the platform's own byte. // -// ## `user.type` is the test; `user.login` is printed, never tested -// -// The card offered them as equivalents (「`user.type !== 'Bot'`, equivalently -// `user.login !== 'claude[bot]'`」) and they are not. `user.type` is the account -// KIND: it answers `Bot` for EVERY App-authored artefact, so a second App on -// this board is judged correctly the day it appears and an App rename changes -// nothing. The login test is a one-name roster wearing an equality sign — it -// judges `github-actions[bot]`, which authored 2 open cards and 1 open PR here, -// as a user account. Measured: those three artefacts carry no signature at all, -// so the two tests agree on TODAY's board and would diverge on the first -// workflow-authored artefact that carries one. This row trusts `user.type`, and -// prints `user.login` because naming the author is the row's job. -// -// An author that cannot be read is DECLINED, never accused: a row whose `user` -// is missing or malformed is counted in the clause and judged by nobody (#4690 -// in the direction that matters here — an unknown must not become an -// accusation). -// -// ## The channel is INFERRED where the payload carries it, and UNREAD where it -// does not -// -// `performed_via_github_app` rides issue rows and comment rows: a slug means -// the write went through that App's tools under a user token (the MCP GitHub -// tool), an absent one means a user PAT. ⚠️ The `/pulls` listing does not serve -// the field AT ALL — measured over all 9 open PRs — so a PR's channel is -// reported as UNREAD with both candidates named, rather than inferred from an -// absence that means nothing here. ⛔ No per-PR fetch is bought to close it. +// ⚠️ The id test reads the WHOLE body, not the signature window: a claim whose +// `Session:` line sits on line 2 is attributed, and so is one whose only id is +// in the footer. The narrow head window belongs to the SIGNATURE (what makes a +// text seat content), never to the attribution (what makes it answerable). +// +// ## `user.login` and `user.type` are PRINTED, never tested +// +// The row names the author because a reader needs to know which token wrote the +// artefact, and stops there. The account is not the defect and not the repair: +// re-posting the same text under a different login leaves it just as +// unattributed. `user.type` still separates the App from a user account for the +// INFORMATIONAL exposure count, where it is the right field — it answers `Bot` +// for EVERY App-authored artefact, so a second App on this board is counted +// correctly the day it appears and an App rename changes nothing, while a login +// test is a one-name roster wearing an equality sign (it would judge +// `github-actions[bot]` a user account). +// +// An author that cannot be read is PRINTED as unread and counted, never +// guessed: the finding is about the text, so an unreadable `user` no longer +// silences it, and the exposure count says it is a lower bound (#4690 in the +// direction that matters here — an unknown must not become an accusation, and +// must not become a clean reading either). // // ## The pin, and why everything before it is a CENSUS // // H55's shape, for H55's reason. The write-shape discipline is 2026-09-13's -// ruling; the board in front of it was written under the older practice, and -// 「re-post it through the proxy」 is not a remedy anyone will perform 164 times. -// So `created_at` before `USER_AUTHORED_WRITE_SINCE` is COUNTED in the summary -// clause and files no row, and on/after it is judged. Measured at the pin: 33 -// open card bodies + 1 open PR body judged, against 164 cards + 3 PRs in the -// census reaching back to 2026-08-07. An unreadable `created_at` is judged, +// ruling; the board in front of it was written under the older practice, and no +// one will go back and re-attribute 600 artefacts by hand. So `created_at` +// before `UNATTRIBUTED_WRITE_SINCE` is COUNTED in the summary clause and files +// no row, and on/after it is judged. An unreadable `created_at` is judged, // never silently legacy. // // `created_at` rather than H55's `updated_at`, and the difference is the // subject: H55 judges an ENTRY into a label state, which has no creation // instant of its own, while this row judges a WRITE, which does. ⚠️ Declared -// residual: an EDIT re-writes a body through the same channel without moving -// `created_at`, so an edited artefact is judged at the instant it was first -// written. This row does not read edit history and buys no timeline page. +// residual: an EDIT re-writes a body without moving `created_at`, so an edited +// artefact is judged at the instant it was first written — which cuts the +// friendly way here, since the remedy IS an edit and a cleared artefact simply +// stops matching. // // ## Why this family CAPS its rows — the renderer's ordering, not a preference // @@ -14363,27 +14411,28 @@ export function h63StaleFindingBesideGrade(issue) { // row's corpus depend on which PRs happened to be governed or gated. // // One row per CARRIER for comments (H44's choice), naming the NEWEST offender -// rather than H44's oldest: the remedy is one re-post per comment either way, -// and the row that reaches a reader should be the one whose subject is still -// this hour's. +// rather than H44's oldest: the remedy is one edit per comment either way, and +// the row that reaches a reader should be the one whose subject is still this +// hour's. // // ## Boundaries, pinned rather than described // // An authorized REVIEW (os-zhuang / hotlong) and the maintainer's own prose are // out of this population TWICE: a review is a `/pulls/{n}/reviews` object this // row never reads, and neither carries a seat signature, so the structural gate -// excludes them before the author is ever consulted. ⛔ That is by construction +// excludes them before anything else is consulted. ⛔ That is by construction // and not by exemption — this row has no exemption list and cannot acquire one // without acquiring the roster it refuses. // --------------------------------------------------------------------------- /** - * The instant from which a seat- or dev-signed write owes the App channel — the - * UTC day of the ruling that put the write-shape discipline in force. Pinned as - * data for `MAINTAINER_ACTION_LINE_SINCE`'s reason: the board in front of it was - * written under the older practice and is a census, not a worklist. + * The instant from which a seat- or dev-signed write owes a session id in its + * own text — the UTC day of the ruling that put the write-shape discipline in + * force. Pinned as data for `MAINTAINER_ACTION_LINE_SINCE`'s reason: the board + * in front of it was written under the older practice and is a census, not a + * worklist. */ -export const USER_AUTHORED_WRITE_SINCE = '2026-09-13T00:00:00Z'; +export const UNATTRIBUTED_WRITE_SINCE = '2026-09-13T00:00:00Z'; /** * How many of the freshest judged findings this family files per run. See the @@ -14394,6 +14443,14 @@ export const USER_AUTHORED_WRITE_SINCE = '2026-09-13T00:00:00Z'; */ export const H64_ROW_CAP = 10; +/** + * How many author logins the INFORMATIONAL exposure clause names before it + * summarises the rest. The roster is what makes the count actionable to a human + * reader; an unbounded one would put the whole board's account list into a body + * that is already trimmed. + */ +export const H64_LOGIN_ROSTER_CAP = 8; + /** A Claude Code session id, as a signature writes it. ⛔ No `g` flag. */ export const SEAT_SESSION_ID = /session_01[0-9A-Za-z]{22}/; @@ -14423,6 +14480,19 @@ export function seatSignatureHead(text, lines = SEAT_SIGNATURE_HEAD_LINES) { return String(text ?? '').split('\n').slice(0, lines).join('\n'); } +/** + * Does this text carry the attribution the landed rule requires — a session id + * ANYWHERE in it? ⛔ Not the head window: the narrow window belongs to the + * SIGNATURE, and an id in a footer or on line 40 attributes the artefact just + * as well as one on line 1. + * + * @param {string} body + * @returns {boolean} + */ +export function seatSessionIdPresent(body) { + return SEAT_SESSION_ID.test(String(body ?? '')); +} + /** * The six signature forms, as data so the self-test can drive each by name and * a reader can check the banner against the tests. Ordered most specific first: @@ -14483,8 +14553,9 @@ export function seatSignature(body) { /** * The author of a REST row, or `null` when the payload does not carry a - * readable one — declined, never read as a user account (#4690 in the direction - * that matters here: an unknown must not become an accusation). + * readable one — reported as unread, never read as a user account (#4690 in the + * direction that matters here: an unknown must not become an accusation, and + * must not become a clean reading either). * * @returns {{ login: string, type: string, isApp: boolean }|null} */ @@ -14497,12 +14568,22 @@ export function artefactAuthor(row) { } /** - * Which channel this write implies, read off `performed_via_github_app`. + * Which APP's credential signed this write, read off `performed_via_github_app` + * — ⛔ and never which TOOL made it. * - * Three states, never two: `'app'` (a slug — the MCP GitHub tool under a user - * token), `'pat'` (the field is served and empty — a user PAT), `'unread'` (the - * payload does not carry the field at all, which is every row the `/pulls` - * listing serves). ⛔ An unread field is never reported as a PAT. + * Three states, never two: `'app'` (a slug — an App credential signed the + * write), `'pat'` (the field is served and empty — a user PAT, outside the App + * entirely), `'unread'` (the payload does not carry the field at all, which is + * every row the `/pulls` listing serves). ⛔ An unread field is never reported + * as a PAT. + * + * ⚠️ Measured 2026-09-15: a REST-proxy comment authored `claude[bot]`, a + * REST-proxy comment authored by a user token, and the four MCP-era specimens + * this family was built from ALL read `{ id: 1236702, slug: 'claude' }`. The + * slug therefore separates an App credential from a PAT and nothing else — the + * banner's measurement block carries the readings, and the self-test pins the + * indistinguishability so the channel inference is not re-derived from this + * function's name. * * @returns {{ kind: 'app'|'pat'|'unread', slug: string|null }} */ @@ -14520,25 +14601,25 @@ export function artefactChannel(row) { * (before it — census), `'judged'` (on/after — a row candidate), `'undated'` * (unreadable — judged, never silently legacy). */ -export function h64EntryClass(row, since = USER_AUTHORED_WRITE_SINCE) { +export function h64EntryClass(row, since = UNATTRIBUTED_WRITE_SINCE) { const at = Date.parse(row?.created_at ?? ''); if (!Number.isFinite(at)) return 'undated'; return at < Date.parse(since) ? 'legacy' : 'judged'; } /** - * Does H64 speak about this text at all? A readable body carrying a signature, - * whose author is readable and is NOT an App. The pin is judged separately, so - * this predicate answers membership and `h64EntryClass` answers freshness. + * Does H64 speak about this text at all? A readable body carrying a seat/dev + * signature and NO session id anywhere. ⛔ The author is not consulted: it is + * printed by the row and counted by the exposure clause, never tested. The pin + * is judged separately, so this predicate answers membership and + * `h64EntryClass` answers freshness. * * @param {{ kind: string, row: object }} text */ export function h64SpeaksAbout(text) { if (typeof text?.row?.body !== 'string') return false; if (!seatSignature(text.row.body)) return false; - const author = artefactAuthor(text.row); - if (!author) return false; - return !author.isApp; + return !seatSessionIdPresent(text.row.body); } /** How the row names each artefact kind. */ @@ -14546,7 +14627,8 @@ export const H64_ARTEFACT_KINDS = Object.freeze(['card', 'pull request', 'commen /** * H64 — `null` when the text is out of scope or legacy, else the finding - * sentence naming the artefact, its author, the channel implied and the remedy. + * sentence naming the artefact, the signature it carries, the token GitHub + * recorded, and the remedy. * * ⛔ No less-than fragment in the sentence: it is rendered into a GitHub issue * body and the platform mutates those, so every placeholder is spelled in @@ -14556,28 +14638,22 @@ export const H64_ARTEFACT_KINDS = Object.freeze(['card', 'pull request', 'commen * @param {number} more — further offending comments on the same carrier. * @param {string} since */ -export function h64UserAuthoredSeatContent(text, more = 0, since = USER_AUTHORED_WRITE_SINCE) { +export function h64UnattributedSeatContent(text, more = 0, since = UNATTRIBUTED_WRITE_SINCE) { if (!h64SpeaksAbout(text)) return null; const entry = h64EntryClass(text.row, since); if (entry === 'legacy') return null; const signature = seatSignature(text.row.body); const author = artefactAuthor(text.row); - const channel = artefactChannel(text.row); const kind = H64_ARTEFACT_KINDS.includes(text.kind) ? text.kind : 'artefact'; const subject = kind === 'comment' ? `comment \`${String(text.row?.id ?? 'an unread id')}\` on this card` : `this open ${kind}`; - const channelClause = - channel.kind === 'app' - ? `The write went through the \`${channel.slug}\` App's tools under that account's token — the MCP ` + - 'GitHub tool channel' - : channel.kind === 'pat' - ? 'The payload carries no `performed_via_github_app`, so the write was made with a user PAT rather ' + - 'than through an App' - : 'The channel is UNREAD rather than inferred: the `/pulls` listing this row reads does not serve ' + - '`performed_via_github_app` at all, so this write is either the MCP GitHub tool or a user PAT and ' + - 'no absence here decides which'; + const authorClause = author + ? `GitHub records its author as \`${author.login}\` (\`user.type\` = \`${author.type}\`), which is the ` + + 'TOKEN that session was handed and not the seat that wrote' + : 'GitHub serves no readable `user` for it, so not even the token is known — the artefact is unattributed ' + + 'on both carriers at once'; const moreClause = more > 0 ? ` ${more} further comment(s) on this carrier carry the same defect; this is the NEWEST.` @@ -14588,49 +14664,60 @@ export function h64UserAuthoredSeatContent(text, more = 0, since = USER_AUTHORED 'unknown reading must not present as a clean one.' : ''; return ( - `${subject} carries ${signature.what} — a seat/dev artefact — while GitHub records its author as ` + - `\`${author.login}\`, a USER account (\`user.type\` = \`${author.type}\`, not \`Bot\`). ${channelClause}. ` + - 'The two carriers disagree about one artefact: the text says a seat or a dev wrote it, the account ' + - 'field says a person did. The cost is not attribution tidiness — a user account that is SUSPENDED ' + - 'hides everything it authored, so the card, the claim or the report leaves every reader at once while ' + - 'staying in the database, and the protocol side controls neither the account nor the moment. Content ' + - 'written through the REST proxy is authored `claude[bot]` (`user.type` `Bot`) and is not affected.' + - `${moreClause}${dated} Remedy — WHO and HOW: the seat or dev that owns the artefact re-posts it ` + - 'through the REST proxy; the original STAYS as history and is neither deleted nor edited into a ' + - 'redirect, because a re-post is a second durable copy and a deletion is one fewer. ⛔ Report-only: ' + - 'this row writes nothing, relabels nothing and re-posts nothing on anyone\'s behalf. Boundaries: an ' + - 'authorized review and the maintainer\'s own prose are out of this population by CONSTRUCTION rather ' + - 'than by exemption — a review is an object this row never reads and neither carries a signature, so ' + - 'the structural gate excludes them before the author is consulted, and ⛔ this row holds no roster of ' + - `accounts to exempt from. Writes created before ${since} are COUNTED in the summary clause and file ` + - 'no row: the board in front of the pin was written under the older practice, and this row is the ' + - 'alarm for what happens now, not a worklist over what happened then.' + `${subject} carries ${signature.what} — a seat/dev artefact — and NO session id appears anywhere in its ` + + `text. ${authorClause}: attribution on this board is the \`session_\` id the text carries, because the ` + + 'write identity follows the CHANNEL and one protocol identity is shared by every agent here ' + + '(`.claude/skills/pm-dispatch/SKILL.md`, `.claude/skills/pm-dispatch/references/rest-channel.md`). The two ' + + 'carriers disagree about one live artefact: the text says a seat or a dev wrote it, and nothing says which ' + + 'session, so a reader who needs the author of this act has nobody to ask and no branch to read.' + + `${moreClause}${dated} Remedy — WHO and HOW: the seat or dev that owns the artefact gives it its session ` + + 'id — an edit in place is enough where the owner can edit, and a re-post carrying the id clears it where ' + + 'editing is not available; the original STAYS as history and is not deleted. ⛔ The ACCOUNT is not the ' + + 'repair: the same text re-posted under a different login is just as unattributed, and this row makes no ' + + 'claim about which channel or which token produced the write. ⛔ Report-only: this row writes nothing, ' + + 'relabels nothing and re-posts nothing on anyone\'s behalf. Boundaries: an authorized review and the ' + + 'maintainer\'s own prose are out of this population by CONSTRUCTION rather than by exemption — a review is ' + + 'an object this row never reads and neither carries a seat signature, so the structural gate excludes them ' + + 'first, and ⛔ this row holds no roster of accounts to exempt from. The separate exposure of a USER-authored ' + + 'artefact to account suspension is reported in the summary clause as INFORMATIONAL with no remedy, and ⛔ ' + + `files no row. Writes created before ${since} are COUNTED in the summary clause and file no row: the board ` + + 'in front of the pin was written under the older practice, and this row is the alarm for what happens now, ' + + 'not a worklist over what happened then.' ); } /** - * The whole family over one run's corpus — census and rows in one pure pass, so - * the two can never describe different populations. + * The whole family over one run's corpus — census, exposure and rows in one + * pure pass, so the three can never describe different populations. * * Comments are grouped per CARRIER (H44's choice) and the NEWEST offender wins * the row; bodies stand alone. Judged rows are ordered newest-first and cut to * `cap` — the banner's ordering argument. * + * `user`, `logins`, `userPat` and `userUnreadChannel` are the INFORMATIONAL + * exposure half: they are counted over every SIGNED text, attributed or not, + * and file no row (the banner says why). + * * @param {{ kind: string, row: object, carrier?: object }[]} texts — every text * this sweep read, bodies and comments alike. * @returns {{ counts: object, rows: { subject: object, message: string }[] }} */ -export function h64Sweep(texts, { since = USER_AUTHORED_WRITE_SINCE, cap = H64_ROW_CAP } = {}) { +export function h64Sweep(texts, { since = UNATTRIBUTED_WRITE_SINCE, cap = H64_ROW_CAP } = {}) { const counts = { texts: 0, signed: 0, + idless: 0, user: 0, + logins: [], + userPat: 0, + userUnreadChannel: 0, legacy: 0, unreadAuthor: 0, oldest: null, judged: 0, rows: 0, }; + const logins = new Set(); const carriers = new Map(); const direct = []; for (const text of texts ?? []) { @@ -14639,12 +14726,16 @@ export function h64Sweep(texts, { since = USER_AUTHORED_WRITE_SINCE, cap = H64_R if (!seatSignature(body)) continue; counts.signed += 1; const author = artefactAuthor(text.row); - if (!author) { - counts.unreadAuthor += 1; - continue; + if (!author) counts.unreadAuthor += 1; + else if (!author.isApp) { + counts.user += 1; + logins.add(author.login); + const channel = artefactChannel(text.row); + if (channel.kind === 'pat') counts.userPat += 1; + else if (channel.kind === 'unread') counts.userUnreadChannel += 1; } - if (author.isApp) continue; - counts.user += 1; + if (seatSessionIdPresent(body)) continue; + counts.idless += 1; const entry = h64EntryClass(text.row, since); if (entry === 'legacy') { counts.legacy += 1; @@ -14670,6 +14761,7 @@ export function h64Sweep(texts, { since = USER_AUTHORED_WRITE_SINCE, cap = H64_R if (stamp > held.stamp) carriers.set(key, { text, stamp, more }); else held.more = more; } + counts.logins = [...logins].sort(); const ordered = [...direct, ...carriers.values()].sort( (a, b) => b.stamp - a.stamp || @@ -14678,7 +14770,7 @@ export function h64Sweep(texts, { since = USER_AUTHORED_WRITE_SINCE, cap = H64_R ); const rows = []; for (const entry of ordered.slice(0, Math.max(0, cap))) { - const message = h64UserAuthoredSeatContent(entry.text, entry.more, since); + const message = h64UnattributedSeatContent(entry.text, entry.more, since); if (!message) continue; rows.push({ subject: entry.text.carrier ?? entry.text.row, message }); } @@ -14686,6 +14778,33 @@ export function h64Sweep(texts, { since = USER_AUTHORED_WRITE_SINCE, cap = H64_R return { counts, rows }; } +/** + * The INFORMATIONAL exposure sentence — a count, a bounded login roster, and + * ⛔ no remedy. Rendered into the summary clause on every run; see the banner + * for why this half files no row. + */ +export function h64ExposureClause(counts = {}, cap = H64_LOGIN_ROSTER_CAP) { + const roster = Array.isArray(counts.seatSignedLogins) ? counts.seatSignedLogins : []; + const named = roster.slice(0, Math.max(0, cap)); + const rest = roster.length - named.length; + const list = + named.length > 0 + ? ` (${named.map((l) => `\`${l}\``).join(', ')}${rest > 0 ? `, and ${rest} more` : ''})` + : ''; + return ( + `INFORMATIONAL, no remedy and no row: ${counts.seatSignedUser ?? 0} signed text(s) are authored by a USER ` + + `account rather than \`claude[bot]\`${list}. A suspended user account hides everything it authored — ` + + 'measured on this board, not hypothetical — so those artefacts carry that exposure; but the token class is ' + + 'handed to a session at start rather than chosen at write time, and no act available to a user-token session ' + + 'moves its content to the App, so this half names NO remedy and files NO row rather than re-filing an ' + + `unclearable one every sweep. ${counts.seatSignedUserPat ?? 0} of them carry no App credential at all (a ` + + `user PAT) and ${counts.seatSignedUserUnreadChannel ?? 0} ride the \`/pulls\` shape that does not serve ` + + '`performed_via_github_app`; ⛔ that field names the APP whose credential signed a write and never the TOOL, ' + + 'so an MCP-tool write and a REST-proxy write under one credential are indistinguishable here and no channel ' + + 'is inferred from it.' + ); +} + // --------------------------------------------------------------------------- // Report rendering — pure over (findings, counts), so `--self-test` pins both // media offline. The live sweep below picks a renderer and prints it; nothing @@ -15005,24 +15124,39 @@ export const SWEEP_COUNT_KEYS = [ 'linkageCardsRead', 'linkageUnread', 'linkageShort', - // H64's census and coverage set (#18069). `seatSignedTexts` is how many texts - // this row judged at all (open card and PR bodies plus the card threads - // already in `commentCache`), `seatSignedSigned` how many carried a seat/dev - // signature and `seatSignedUser` how many of THOSE are authored by a user - // account — the finding population, legacy and judged together. - // `seatSignedLegacy`/`seatSignedOldest` are the census behind the pin, - // `seatSignedUnreadAuthor` the rows whose `user` could not be read (declined, - // never accused) and `seatSignedRows` how many of the judged findings this - // family actually FILED under its own cap — without that last number a capped - // run and a quiet board render identically. + // H64's census, coverage and EXPOSURE set (#18069, re-keyed by #18237). + // `seatSignedTexts` is how many texts this row judged at all (open card and + // PR bodies plus the card threads already in `commentCache`), + // `seatSignedSigned` how many carried a seat/dev signature and + // `seatSignedIdless` how many of THOSE name no session id anywhere — the + // finding population, legacy and judged together. + // `seatSignedLegacy`/`seatSignedOldest` are the census behind the pin and + // `seatSignedRows` how many of the judged findings this family actually FILED + // under its own cap — without that last number a capped run and a quiet board + // render identically. + // + // The remaining four are the INFORMATIONAL exposure half, which files no row, + // so the clause is the ONLY place a reader sees it: `seatSignedUser` is how + // many signed texts are authored by a user account, `seatSignedLogins` the + // bounded roster of those logins (an ARRAY, not a counter — it rides this + // contract for `governedRegisterReason`'s reason: a clause that could only + // render a number would state an exposure nobody can act on), and + // `seatSignedUserPat`/`seatSignedUserUnreadChannel` the two credential + // readings that are NOT an App slug. `seatSignedUnreadAuthor` is how many + // signed texts carried no readable `user` at all, which makes the exposure + // count a lower bound rather than a census. 'seatSignedTexts', 'seatSignedSigned', - 'seatSignedUser', + 'seatSignedIdless', 'seatSignedJudged', 'seatSignedLegacy', 'seatSignedOldest', - 'seatSignedUnreadAuthor', 'seatSignedRows', + 'seatSignedUser', + 'seatSignedLogins', + 'seatSignedUserPat', + 'seatSignedUserUnreadChannel', + 'seatSignedUnreadAuthor', 'refBeyond', ]; @@ -15495,20 +15629,22 @@ export function summaryLine(counts, findingCount) { // purchase in this file that is a per-card timeline page, its cap, and the // measured fact that the commit leg fires on nothing here. `Merged-PR closing linkage (H59): ${h59LinkageClause(counts)} ` + - // H64's census and coverage set (#18069). UNCONDITIONAL like every other - // window's, and it is the only place three of this row's readings are - // visible at all: the population behind the pin (a census that files no - // row), the authors that could not be read (declined, never accused), and - // how many judged findings the family's own cap left unfiled. - `User-authored seat content (H64): ${counts.seatSignedSigned ?? 0} of ${counts.seatSignedTexts ?? 0} ` + - `text(s) read carry a seat/dev signature; ${counts.seatSignedUser ?? 0} of those are authored by a ` + - `USER account rather than \`claude[bot]\` — ${counts.seatSignedJudged ?? 0} created on/after ` + - `${USER_AUTHORED_WRITE_SINCE} and judged, ${counts.seatSignedRows ?? 0} filed as rows under this ` + + // H64's census, coverage and exposure set (#18069, re-keyed by #18237). + // UNCONDITIONAL like every other window's, and it is the only place four of + // this row's readings are visible at all: the population behind the pin (a + // census that files no row), how many judged findings the family's own cap + // left unfiled, the authors that could not be read, and the whole + // INFORMATIONAL exposure half, which deliberately files no row. + `Unattributed seat content (H64): ${counts.seatSignedSigned ?? 0} of ${counts.seatSignedTexts ?? 0} ` + + `text(s) read carry a seat/dev signature; ${counts.seatSignedIdless ?? 0} of those name no session id ` + + `anywhere — ${counts.seatSignedJudged ?? 0} created on/after ` + + `${UNATTRIBUTED_WRITE_SINCE} and judged, ${counts.seatSignedRows ?? 0} filed as rows under this ` + `family's own ${H64_ROW_CAP}-row cap (newest first, because the body trim eats the highest card ` + `numbers), and ${counts.seatSignedLegacy ?? 0} counted here as a CENSUS` + `${counts.seatSignedOldest ? ` reaching back to ${counts.seatSignedOldest}` : ''}. ` + - `${counts.seatSignedUnreadAuthor ?? 0} signed text(s) carried no readable \`user\` and were ` + - 'DECLINED rather than accused. It fetches NOTHING of its own: the corpus is the open card and PR ' + + `${h64ExposureClause(counts)} ` + + `${counts.seatSignedUnreadAuthor ?? 0} signed text(s) carried no readable \`user\`, so the exposure ` + + 'count is a lower bound. It fetches NOTHING of its own: the corpus is the open card and PR ' + 'bodies in hand plus the card threads H44 and H56 read, so a PULL-REQUEST comment thread is outside ' + 'it by construction and these numbers are a LOWER BOUND. ' + `Report-only: findings are patrol input, not a gate verdict.` @@ -15573,7 +15709,7 @@ export const SUMMARY_CLAUSE_ANCHORS = [ ['h57Scheduled', 'Scheduled non-blocking workflows (H57): '], ['h58RulingMarkers', 'Queued ruling markers (H58): '], ['h59Linkage', 'Merged-PR closing linkage (H59): '], - ['h64SeatSigned', 'User-authored seat content (H64): '], + ['h64SeatSigned', 'Unattributed seat content (H64): '], ['reportOnly', 'Report-only: '], ]; @@ -20531,7 +20667,8 @@ async function sweepInto(findings, seen, seenPrs, seenMerged, seenUnscoped, seen stats.stampUnjudged = h56Unjudged; stats.stampAmbiguous = h56Held; - // H64 (#18069) — the user-authored seat/dev write. Placed HERE, after H56 and + // H64 (#18069, re-keyed by #18237) — the seat/dev write that names no + // session. Placed HERE, after H56 and // BEFORE H46, for H56's reason in H56's words: H46's leg (b) widens // `commentCache`, so judging this row after it would hand H64 a comment // corpus H44 and H56 never saw and the three clauses would stop describing @@ -20558,12 +20695,16 @@ async function sweepInto(findings, seen, seenPrs, seenMerged, seenUnscoped, seen for (const row of h64.rows) findings.push([row.subject, 'H64', row.message]); stats.seatSignedTexts = h64.counts.texts; stats.seatSignedSigned = h64.counts.signed; - stats.seatSignedUser = h64.counts.user; + stats.seatSignedIdless = h64.counts.idless; stats.seatSignedJudged = h64.counts.judged; stats.seatSignedLegacy = h64.counts.legacy; stats.seatSignedOldest = h64.counts.oldest; - stats.seatSignedUnreadAuthor = h64.counts.unreadAuthor; stats.seatSignedRows = h64.counts.rows; + stats.seatSignedUser = h64.counts.user; + stats.seatSignedLogins = h64.counts.logins; + stats.seatSignedUserPat = h64.counts.userPat; + stats.seatSignedUserUnreadChannel = h64.counts.userUnreadChannel; + stats.seatSignedUnreadAuthor = h64.counts.unreadAuthor; // H46 — the claim-less implementation. Placed HERE, AFTER H44, deliberately: // leg (b) adds threads to `commentCache`, and H44's corpus is whatever the @@ -24059,29 +24200,55 @@ async function selfTest() { t('H63 band: no code is left unregistered by this change', familyRegistryCoverage().missing.length, 0); t('H63 band: …and none is registered that the sweep never pushes', familyRegistryCoverage().extra.length, 0); - // -- H64 — a seat- or dev-signed artefact authored by a USER account (#18069) + // -- H64 — a seat- or dev-signed artefact that names no session (#18069, + // re-keyed by #18237) --------------------------------------------------- // // ⛔ The self-test never touches GitHub. Every fixture below is an OFFLINE row - // whose fields are the specimens measured on this board 2026-09-13: #18045 and - // objectui#9404 (cards authored `os-project-manager`, bodies signed by the - // skills seat), PR #18051 (authored `os-project-manager`, signed by a dev - // session in its attribution footer), comment 5652138683 on objectui#9370 - // (authored `os-tesla`), and comment 5654046782 on #18045 as the clean - // `claude[bot]` control. Every fire has a lit control differing in exactly one - // feature, and every silence has one too. + // whose fields are specimens measured on this board. The four from 2026-09-13: + // #18045 and objectui#9404 (cards authored `os-project-manager`, bodies signed + // by the skills seat), PR #18051 (authored `os-project-manager`, signed by a + // dev session in its attribution footer) and comment 5652138683 on + // objectui#9370 (authored `os-tesla`), with comment 5654046782 on #18045 as + // the `claude[bot]` control. Two more from 2026-09-15, added by the re-keying: + // comment 5673548571 (a REST-proxy write authored `claude[bot]`) and comment + // 5673265919 (a REST-proxy write authored by a USER token). That last pair is + // why no channel is inferred here — both carry `{ id: 1236702, slug: 'claude' }`. + // + // ⚠️ Three of the four original specimens changed SIDES under the re-keying, + // and each is pinned on its new side with its reason, because a reader + // comparing this suite to #18069 must see a re-classification rather than a + // deletion: + // + // #18045 its bare session id sits on line 1 — ATTRIBUTED, clean. + // ⛔ And that id is its ONLY signature (`Filed and claimed + // by` is not the filing header), so striking the id does not + // make it fire — it leaves the population entirely. + // objectui#9404 the same id sits beside its filing header — clean; strike + // the id and the filer form still sees it, so THIS is the + // specimen that carries the lit control. + // PR #18051 its ONLY id is in the footer on line 45 of 45 — clean, + // because the id test reads the WHOLE body while the + // signature's head window stays narrow. + // 5652138683 names its seat by ACCOUNT (`os-tesla`) and carries NO + // session id in 35 lines — STILL FIRES, and it is now this + // row's live positive rather than one specimen of four. + // + // Every fire has a lit control differing in exactly one feature, and every + // silence has one too. const user64 = (login) => ({ login, type: 'User' }); const APP64 = { login: 'claude[bot]', type: 'Bot' }; const FOOTER64 = '_Generated by [Claude Code](https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8)_'; const BARE_FOOTER64 = '_Generated by [Claude Code](https://claude.ai/code)_'; // #18045 — the bare session id on the FIRST line; ⛔ `Filed and claimed by` - // is not the filing header, which is why this specimen fires on the id alone. + // is not the filing header, which is why the id is this specimen's whole + // signature as well as its attribution. const card18045 = (extra = {}) => ({ number: 18045, state: 'open', created_at: '2026-09-13T14:59:12Z', user: user64('os-project-manager'), - performed_via_github_app: { slug: 'claude' }, + performed_via_github_app: { id: 1236702, slug: 'claude' }, body: '**Maintainer direct dispatch** — the maintainer in the skills seat\'s chat session at ' + '2026-09-13T14:58Z. Filed and claimed by the skills seat (session ' + @@ -24089,18 +24256,28 @@ async function selfTest() { '## Symptom\n- the archive walk is behind\n', ...extra, }); + // The same card with its id struck — ⛔ NOT a fire: the id was the signature. + const BODY18045_NOID = + '**Maintainer direct dispatch** — the maintainer in the skills seat\'s chat session at ' + + '2026-09-13T14:58Z. Filed and claimed by the skills seat under the direct-dispatch ' + + 'channel.\n\n## Symptom\n- the archive walk is behind\n'; // objectui#9404 — the FILING HEADER, which outranks the id on the same line. const card9404 = (extra = {}) => ({ number: 9404, state: 'open', created_at: '2026-09-13T15:31:22Z', user: user64('os-project-manager'), - performed_via_github_app: { slug: 'claude' }, + performed_via_github_app: { id: 1236702, slug: 'claude' }, body: 'Filed by the skills seat (session `session_01DAcomhvR9kKizeYgg89Vo8`) as a bare card in this ' + 'round\'s filing batch: ⛔ not routed, not graded.\n\nDedupe keywords: `checklist`.\n', ...extra, }); + // …and the one-feature control: the same filing header with NO id anywhere. + const BODY9404_NOID = + 'Filed by the skills seat as a bare card in this round\'s filing batch: ⛔ not routed, not ' + + 'graded.\n\nDedupe keywords: `checklist`.\n'; + const noid64 = (number, extra = {}) => card9404({ number, body: BODY9404_NOID, ...extra }); // PR #18051 — the `/pulls` shape: ⛔ NO `performed_via_github_app` key at all, // and the ONLY session token is in the footer on the LAST line. const pr18051 = (extra = {}) => ({ @@ -24111,34 +24288,59 @@ async function selfTest() { body: `Fixes #18019\n\nThree governed lines still carried pre-ruling text.\n\n---\n${FOOTER64}`, ...extra, }); - // Comment 5652138683 — a `Claim:` block with ⛔ NO `Session:` line anywhere. + // …and the same PR body signed by its filing header with only the platform's + // BARE footer under it — the shape that fires on the `/pulls` corpus. + const BODY18051_NOID = + 'Fixes #18019\n\nFiled by the `domain:spec` dev.\n\nThree governed lines still carried ' + + `pre-ruling text.\n\n---\n${BARE_FOOTER64}`; + // Comment 5652138683 — a `Claim:` block with ⛔ NO `Session:` line anywhere, + // naming its seat by ACCOUNT. This row's live positive. const comment5652138683 = (extra = {}) => ({ id: 5652138683, created_at: '2026-09-13T08:11:05Z', user: user64('os-tesla'), - performed_via_github_app: { slug: 'claude' }, + performed_via_github_app: { id: 1236702, slug: 'claude' }, body: 'Claim: objectui#9370 — move the three published guides off the retired root\n' + - 'Clause-②: yes\n\n**Claimed by the `domain:ui` PM seat — dispatched this round.**\n\n---\n' + + 'Clause-②: yes\n\n**Claimed by the `domain:ui` PM seat (`os-tesla`) — dispatched this ' + + 'round.**\n\n---\n' + BARE_FOOTER64, ...extra, }); - // Comment 5654046782 — the clean control: the SAME claim shape, authored by - // the App. + // Comment 5654046782 — the clean control: the same claim shape, authored by + // the App AND carrying its session on the `Session:` line. const comment5654046782 = (extra = {}) => ({ id: 5654046782, created_at: '2026-09-13T14:59:48Z', user: APP64, - performed_via_github_app: { slug: 'claude' }, + performed_via_github_app: { id: 1236702, slug: 'claude' }, body: 'Claim: PM loop round 1\nSession: `session_01DAcomhvR9kKizeYgg89Vo8` (GitHub ' + '`os-project-manager`, skills seat), claimed at 2026-09-13T14:59Z\n' + 'Branch: `claude/issue-18045-archive-walk`\n', ...extra, }); + // The 2026-09-15 pair that retired the channel inference: one REST-proxy write + // per TOKEN CLASS, fields as measured. + const restBot64 = (extra = {}) => ({ + id: 5673548571, + created_at: '2026-09-15T02:03:14Z', + user: APP64, + performed_via_github_app: { id: 1236702, slug: 'claude' }, + body: 'Round-open marker — R1 · session `session_01HZfg2AwVX191qCizp88gQr`\n', + ...extra, + }); + const restUser64 = (extra = {}) => ({ + id: 5673265919, + created_at: '2026-09-15T01:27:00Z', + user: user64('os-warren'), + performed_via_github_app: { id: 1236702, slug: 'claude' }, + body: 'Filed by the `domain:spec` seat (session `session_01KB5PFtxuy1x3dcR5gxudx6`).\n', + ...extra, + }); const carrier64 = { number: 18045, html_url: 'https://example.invalid/18045' }; const text64 = (kind, row, carrier) => ({ kind, row, carrier }); - const row64 = (text, more = 0) => String(h64UserAuthoredSeatContent(text, more) ?? ''); + const row64 = (text, more = 0) => String(h64UnattributedSeatContent(text, more) ?? ''); // ⛔ Every reader below goes through a wrapper, for the row-wrapper note's // reason one level down: `seatSignature` and `artefactAuthor` are // THREE-VALUED by design, so a bare `.kind` / `.isApp` throws while `t()`'s @@ -24149,128 +24351,148 @@ async function selfTest() { const sig64 = (body) => seatSignature(body)?.kind ?? null; const isApp64 = (row) => artefactAuthor(row)?.isApp ?? null; const message64 = (result, i = 0) => String(result?.rows?.[i]?.message ?? ''); - - // ── Direction 1: the four measured specimens all FIRE ───────────────────── - t('H64 fires: #18045 — a card body carrying a bare session id, authored by a user account', typeof h64UserAuthoredSeatContent(text64('card', card18045())), 'string'); - t('H64 fires: objectui#9404 — the filing header, same account', typeof h64UserAuthoredSeatContent(text64('card', card9404())), 'string'); - t('H64 fires: PR #18051 — a dev-signed body on the pulls shape', typeof h64UserAuthoredSeatContent(text64('pull request', pr18051())), 'string'); - t('H64 fires: comment 5652138683 — an os-tesla claim on a card thread', typeof h64UserAuthoredSeatContent(text64('comment', comment5652138683(), carrier64)), 'string'); - - // ── The two widenings the MEASUREMENT forced, pinned as measurements ────── + const claim64 = () => text64('comment', comment5652138683(), carrier64); + + // ── Direction 1: the live positive, and the three specimens that moved ──── + t('H64 fires: comment 5652138683 — an os-tesla claim naming its seat by ACCOUNT and no session at all', typeof h64UnattributedSeatContent(claim64()), 'string'); + t('H64 fires: …and the one-feature control clears it — the SAME claim with a `Session:` line is silent', h64UnattributedSeatContent(text64('comment', comment5652138683({ body: 'Claim: objectui#9370\nSession: `session_01DAcomhvR9kKizeYgg89Vo8`\n' }), carrier64)), null); + t('⛔ H64: #18045 is ATTRIBUTED — its bare session id on line 1 is exactly what the landed rule asks for', h64UnattributedSeatContent(text64('card', card18045())), null); + t('⛔ H64: …and striking that id does NOT make it fire — the id was its only signature', h64UnattributedSeatContent(text64('card', card18045({ body: BODY18045_NOID }))), null); + t('H64: …which is a claim about the SIGNATURE, pinned so the silence is not read as a gap', sig64(BODY18045_NOID), null); + t('⛔ H64: objectui#9404 is ATTRIBUTED — the filing header sits beside the id', h64UnattributedSeatContent(text64('card', card9404())), null); + t('H64 fires: …and the same filing header with NO id anywhere fires, so it is the ID that decides', typeof h64UnattributedSeatContent(text64('card', card9404({ body: BODY9404_NOID }))), 'string'); + t('⛔ H64: PR #18051 is ATTRIBUTED — its ONLY id is in the footer on the last line', h64UnattributedSeatContent(text64('pull request', pr18051())), null); + t('H64 fires: …and a `/pulls` body signed by its filer with only the platform BARE footer fires', typeof h64UnattributedSeatContent(text64('pull request', pr18051({ body: BODY18051_NOID }))), 'string'); + t('H64: the id test reads the WHOLE body, ⛔ not the signature head window', seatSessionIdPresent(pr18051().body) && !SEAT_SESSION_ID.test(seatSignatureHead(pr18051().body)), true); + + // ── The structural consequence: two of the six forms can never fire ─────── + t('H64 structure: the `session` form IS an id, so a text matching it carries its own attribution', sig64('line one\nline two\nsession_01DAcomhvR9kKizeYgg89Vo8'), 'session'); + t('H64 structure: …and therefore leaves the population by construction', h64SpeaksAbout(text64('card', card18045({ body: 'line one\nline two\nsession_01DAcomhvR9kKizeYgg89Vo8' }))), false); + t('H64 structure: the `footer` form likewise', sig64(`prose\n\n---\n${FOOTER64}`), 'footer'); + t('H64 structure: …and it too can never fire', h64SpeaksAbout(text64('card', card18045({ body: `prose\n\n---\n${FOOTER64}` }))), false); + t('H64 structure: the other four forms CAN fire — a claim with no id is the population', h64SpeaksAbout(claim64()), true); + t('⛔ H64 structure: …and the BARE footer, the one the platform appends itself, is not a signature at all', sig64(`prose\n\n---\n${BARE_FOOTER64}`), null); + + // ── The two widenings the 2026-09-13 MEASUREMENT forced, still pinned ───── t('H64 widening: the os-tesla specimen carries NO `Session:` line', /^\s*>?\s*Session\s*:/m.test(comment5652138683().body), false); - t('H64 widening: …so the claim form is `CLAIM_COMMENT_MARKER` alone, and the specimen still fires', sig64(comment5652138683().body), 'claim'); + t('H64 widening: …so the claim form is `CLAIM_COMMENT_MARKER` alone, and the specimen still reads as a claim', sig64(comment5652138683().body), 'claim'); t('H64 widening: PR #18051 carries NO session id in its first three lines', SEAT_SESSION_ID.test(seatSignatureHead(pr18051().body)), false); - t('H64 widening: …so the FOOTER is a sixth form, and the specimen fires on it', sig64(pr18051().body), 'footer'); - t('H64 widening: ⛔ and the BARE footer — the one the platform appends itself — is NOT a signature', sig64(`prose\n\n---\n${BARE_FOOTER64}`), null); - - // ── Direction 2: the AUTHOR is what fires it — lit controls both ways ───── - t('⛔ H64: the clean control — comment 5654046782, the same claim shape authored `claude[bot]`', h64UserAuthoredSeatContent(text64('comment', comment5654046782(), carrier64)), null); - t('H64 control: …and the byte-identical comment under a USER login fires, so it is the ACCOUNT that decides', typeof h64UserAuthoredSeatContent(text64('comment', comment5654046782({ user: user64('os-tesla') }), carrier64)), 'string'); - t('⛔ H64: #18045 authored by the App is clean', h64UserAuthoredSeatContent(text64('card', card18045({ user: APP64 }))), null); - t('⛔ H64: an UNSIGNED body under a user account is not this row — no signature, no population', h64UserAuthoredSeatContent(text64('card', card18045({ body: 'The archive walk is behind. Please look.' }))), null); - t('H64 control: …and the same prose with one claim line fires', typeof h64UserAuthoredSeatContent(text64('card', card18045({ body: 'Claim: PM loop round 1\nThe archive walk is behind.' }))), 'string'); - - // ⭐ The boundary the filing card asked to be pinned: approver reviews and the - // maintainer's own prose are out by CONSTRUCTION, ⛔ never by exemption. - t('⛔ H64 boundary: the maintainer\'s own prose carries no seat signature and is out', h64UserAuthoredSeatContent(text64('comment', comment5652138683({ user: user64('hotlong'), body: '同意,按这个方向做。' }), carrier64)), null); - t('H64 boundary: …and the SAME login carrying a signature DOES fire — the row holds no exemption list', typeof h64UserAuthoredSeatContent(text64('comment', comment5652138683({ user: user64('hotlong') }), carrier64)), 'string'); - t('⛔ H64 boundary: an approver\'s review text carries no signature either — a `Reviewed-by:` line alone is not the form', h64UserAuthoredSeatContent(text64('comment', comment5652138683({ user: user64('os-zhuang'), body: 'Reviewed-by: os-zhuang\n\nLooks right to me.' }), carrier64)), null); - t('H64 boundary: …and the same text UNDER the review heading is a seat artefact and fires', typeof h64UserAuthoredSeatContent(text64('comment', comment5652138683({ user: user64('os-zhuang'), body: '## Contract review — PASS\n\nReviewed-by: os-zhuang\n' }), carrier64)), 'string'); - t('H64 boundary: ⛔ the two approver logins appear NOWHERE in this row\'s source-level vocabulary', SEAT_SIGNATURE_FORMS.some((f) => /zhuang|hotlong/.test(String(f.what))), false); - - // ── `user.type` is the test; `user.login` is printed, never tested ──────── + t('H64 widening: …so the FOOTER is a sixth form, and the specimen reads on it', sig64(pr18051().body), 'footer'); + + // ── Direction 2: the author is PRINTED, ⛔ never tested ─────────────────── + t('H64 author: a `claude[bot]`-authored claim with no session id FIRES — the account was never the test', typeof h64UnattributedSeatContent(text64('comment', comment5652138683({ user: APP64 }), carrier64)), 'string'); + t('⛔ H64 author: …and comment 5654046782 — the App-authored claim that DOES name its session — is clean', h64UnattributedSeatContent(text64('comment', comment5654046782(), carrier64)), null); + t('H64 author: …as is the byte-identical comment under a USER login, because the ID decides and the login does not', h64UnattributedSeatContent(text64('comment', comment5654046782({ user: user64('os-tesla') }), carrier64)), null); + t('H64 author: the row names the login it read', row64(claim64()).includes('`os-tesla`'), true); + t('H64 author: …and says that login is the TOKEN the session was handed, not the seat', row64(claim64()).includes('TOKEN that session was handed and not the seat that wrote'), true); + t('H64 author: an unreadable `user` no longer silences the row — the finding is about the TEXT', typeof h64UnattributedSeatContent(text64('comment', comment5652138683({ user: undefined }), carrier64)), 'string'); + t('H64 author: …and the row says so rather than guessing one', row64(text64('comment', comment5652138683({ user: undefined }), carrier64)).includes('serves no readable `user`'), true); t('H64 author: a `Bot` type is an App, whatever its login', isApp64({ user: { login: 'some-app[bot]', type: 'Bot' } }), true); t('H64 author: a `User` type is a user account, whatever its login', isApp64({ user: { login: 'claude[bot]', type: 'User' } }), false); - t('⛔ H64 author: `github-actions[bot]` is an App and is NOT this row — the login test would have judged it a user', h64UserAuthoredSeatContent(text64('card', card18045({ user: { login: 'github-actions[bot]', type: 'Bot' } }))), null); - t('H64 author: …and the two tests are NOT equivalent, which is why the type one is trusted', 'github-actions[bot]' !== 'claude[bot]' && isApp64({ user: { login: 'github-actions[bot]', type: 'Bot' } }) === true, true); - t('⛔ H64 author: an unreadable `user` is DECLINED, never accused', h64UserAuthoredSeatContent(text64('card', card18045({ user: undefined }))), null); - t('⛔ H64 author: …and a `user` with no `type` likewise', artefactAuthor({ user: { login: 'os-bill' } }), null); + t('⛔ H64 author: …and a `user` with no `type` is unreadable', artefactAuthor({ user: { login: 'os-bill' } }), null); t('⛔ H64 author: …and one with no `login`', artefactAuthor({ user: { type: 'User' } }), null); t('⛔ H64 author: a missing row does not crash', artefactAuthor(undefined), null); - t('⛔ H64: a missing text does not crash', h64UserAuthoredSeatContent(undefined), null); - - // ── The channel: three states, ⛔ never two ─────────────────────────────── - t('H64 channel: a slug means the App\'s tools under a user token', artefactChannel(card18045()).kind, 'app'); - t('H64 channel: …and the row names that slug', row64(text64('card', card18045())).includes('`claude` App'), true); - t('H64 channel: the field served and EMPTY means a user PAT', artefactChannel({ performed_via_github_app: null }).kind, 'pat'); + t('⛔ H64: a missing text does not crash', h64UnattributedSeatContent(undefined), null); + t('⛔ H64: an UNSIGNED body is not this row — no signature, no population', h64UnattributedSeatContent(text64('card', card18045({ body: 'The archive walk is behind. Please look.' }))), null); + t('H64: …and the same prose with one claim line fires', typeof h64UnattributedSeatContent(text64('card', card18045({ body: 'Claim: PM loop round 1\nThe archive walk is behind.' }))), 'string'); + + // ── Direction 3: the channel reading that #18237 retired ───────────────── + t('H64 channel: the REST-proxy comment authored `claude[bot]` reads slug `claude`', artefactChannel(restBot64()).slug, 'claude'); + t('H64 channel: …and the REST-proxy comment authored by a USER token reads the SAME slug', artefactChannel(restUser64()).slug, 'claude'); + t('H64 channel: …so one field cannot separate the two token classes, let alone the two TOOLS', artefactChannel(restBot64()).slug === artefactChannel(restUser64()).slug, true); + t('⛔ H64 channel: the row therefore names no channel — the retired sentence accused a tool it could not read', row64(claim64()).includes('MCP'), false); + t('⛔ H64 channel: …and prescribes no re-post through the REST proxy, the remedy that could not clear it', row64(claim64()).includes('re-posts it through the REST proxy'), false); + t('⛔ H64 channel: …nor does it claim REST writes are authored `claude[bot]`, the superseded premise', row64(claim64()).includes('written through the REST proxy is authored'), false); + t('H64 channel: …and it says outright that it makes no channel claim', row64(claim64()).includes('makes no claim about which channel or which token produced the write'), true); + t('H64 channel: what the slug still separates is an App credential from none', artefactChannel({ performed_via_github_app: null }).kind, 'pat'); t('H64 channel: the field ABSENT is UNREAD — the `/pulls` shape, ⛔ never inferred as a PAT', artefactChannel(pr18051()).kind, 'unread'); - t('H64 channel: …and the PR row says UNREAD rather than guessing', row64(text64('pull request', pr18051())).includes('The channel is UNREAD rather than inferred'), true); - t('H64 channel: …naming both candidates so a reader is not left with an absence', row64(text64('pull request', pr18051())).includes('either the MCP GitHub tool or a user PAT'), true); t('H64 channel: a missing row is UNREAD, never a PAT', artefactChannel(undefined).kind, 'unread'); - - // ── The six signature forms, driven WHOLE so none is quietly dropped ────── - t('H64 forms: the table is exercised whole — six forms', SEAT_SIGNATURE_FORMS.length, 6); - t('H64 forms: the marker for a claim is the file\'s own, ⛔ not a second spelling', SEAT_SIGNATURE_FORMS[0].test('Claim: x') === CLAIM_COMMENT_MARKER.test('Claim: x'), true); - t('H64 forms: …and the report marker likewise', sig64('os-dev-report\n\n```json\n{}\n```'), 'report'); - t('H64 forms: …and the review form needs BOTH halves', sig64('## Contract review — PASS\n\nReviewed-by: os-zhuang'), 'review'); - t('⛔ H64 forms: …a review HEADING with no `Reviewed-by:` line is not the form', sig64('## Contract review — PASS\n\nLooks fine.'), null); - t('H64 forms: the filing header reads through its measured decorations', sig64('⛔ **Filed by the `domain:cli` execution PM seat** (#6024)'), 'filer'); - t('H64 forms: …and a blockquoted one', sig64('> Filed by the PM seat via the maintainer direct-dispatch channel'), 'filer'); - t('⛔ H64 forms: …but not a mention buried mid-paragraph', sig64('This card was in the end not Filed by the skills seat at all, it was filed by hand.'), null); - t('H64 forms: a bare session id in the head window reads', sig64('line one\nline two\nsession_01DAcomhvR9kKizeYgg89Vo8'), 'session'); - t('⛔ H64 forms: …one on the FOURTH line does not — a quoted id mid-body is prose', sig64('one\ntwo\nthree\nsession_01DAcomhvR9kKizeYgg89Vo8'), null); - t('⛔ H64 forms: prose containing the word claim is not a claim', sig64('The seat will claim this next round.'), null); - t('⛔ H64 forms: an empty body carries no signature', sig64(''), null); - t('⛔ H64 forms: …and neither does a missing one', sig64(undefined), null); - t('H64 forms: ORDER — the filing header outranks the footer on one body', sig64(`Filed by the skills seat\n\n---\n${FOOTER64}`), 'filer'); - t('H64 forms: …and the claim outranks everything', sig64(`Claim: x\nFiled by the skills seat\n\n---\n${FOOTER64}`), 'claim'); - - // ── The pin: legacy is a CENSUS, judged is a row, undated is judged ─────── - t('⛔ H64 pin: a write created BEFORE the pin files no row', h64UserAuthoredSeatContent(text64('card', card18045({ created_at: '2026-09-12T23:59:59Z' }))), null); - t('H64 pin: …and one created ON the pin instant fires', typeof h64UserAuthoredSeatContent(text64('card', card18045({ created_at: USER_AUTHORED_WRITE_SINCE }))), 'string'); + t('H64 channel: …and the exposure clause states the limit so it is not re-derived from the reader\'s name', h64ExposureClause({}).includes('names the APP whose credential signed a write and never the TOOL'), true); + + // ── Direction 4: the INFORMATIONAL exposure — counted, never filed ──────── + t('H64 exposure: the clause counts the user-authored signed texts', h64ExposureClause({ seatSignedUser: 671 }).includes('671 signed text(s) are authored by a USER account'), true); + t('H64 exposure: …and names the logins, so the count is something a reader can act on', h64ExposureClause({ seatSignedLogins: ['os-tesla', 'os-warren'] }).includes('(`os-tesla`, `os-warren`)'), true); + t('H64 exposure: …bounded by the roster cap, which says how many it did not name', h64ExposureClause({ seatSignedLogins: Array.from({ length: H64_LOGIN_ROSTER_CAP + 3 }, (unused, i) => `os-${i}`) }).includes('and 3 more'), true); + t('H64 exposure: …and names no roster at all when nothing was read', h64ExposureClause({}).includes('account rather than `claude[bot]`.'), true); + t('H64 exposure: the suspension hazard is stated, ⛔ not relaxed', h64ExposureClause({}).includes('A suspended user account hides everything it authored'), true); + t('H64 exposure: …as measured on this board rather than hypothetical', h64ExposureClause({}).includes('measured on this board, not hypothetical'), true); + t('⛔ H64 exposure: …and it names NO remedy, which is the whole reason it files no row', h64ExposureClause({}).includes('names NO remedy and files NO row'), true); + t('H64 exposure: …and says why no remedy exists — the token class is handed to a session, not chosen', h64ExposureClause({}).includes('handed to a session at start rather than chosen at write time'), true); + t('H64 exposure: the PAT reading and the unread-channel reading are separate numbers', h64ExposureClause({ seatSignedUserPat: 2, seatSignedUserUnreadChannel: 5 }).includes('2 of them carry no App credential at all (a user PAT) and 5 ride'), true); + t('H64 exposure: a bare clause renders numbers, never `undefined`', h64ExposureClause({}).includes('undefined'), false); + t('H64 exposure: ⛔ no less-than fragment — it is rendered into a GitHub issue body', /[<>]/.test(h64ExposureClause({ seatSignedLogins: ['os-warren'] })), false); + + // ── The pin: a census behind it, judged on and after it ────────────────── + t('⛔ H64 pin: a write created BEFORE the pin files no row', h64UnattributedSeatContent(text64('card', noid64(9404, { created_at: '2026-09-12T23:59:59Z' }))), null); + t('H64 pin: …and one created ON the pin instant fires', typeof h64UnattributedSeatContent(text64('card', noid64(9404, { created_at: UNATTRIBUTED_WRITE_SINCE }))), 'string'); t('H64 pin: the class of a pre-pin write is `legacy`', h64EntryClass(card18045({ created_at: '2026-08-07T15:16:20Z' })), 'legacy'); t('H64 pin: …a post-pin one is `judged`', h64EntryClass(card18045()), 'judged'); t('H64 pin: …and an unreadable `created_at` is `undated`, ⛔ never silently legacy', h64EntryClass(card18045({ created_at: 'nope' })), 'undated'); - t('H64 pin: an undated write is JUDGED and the row says why', row64(text64('card', card18045({ created_at: 'nope' }))).includes('could not be read, so it is judged'), true); - t('H64 pin: the row names the pin so a reader knows what the census holds', row64(text64('card', card18045())).includes(USER_AUTHORED_WRITE_SINCE), true); + t('H64 pin: an undated write is JUDGED and the row says why', row64(text64('card', noid64(9404, { created_at: 'nope' }))).includes('could not be read, so it is judged'), true); + t('H64 pin: the row names the pin so a reader knows what the census holds', row64(claim64()).includes(UNATTRIBUTED_WRITE_SINCE), true); t('H64 pin: it is `created_at` that is read — a WRITE has a creation instant', h64EntryClass({ created_at: '2026-09-13T00:00:01Z', updated_at: '2020-01-01T00:00:00Z' }), 'judged'); // ── The sentence: what it must carry, and what it must not ─────────────── - t('H64 row: it names the author login', row64(text64('card', card18045())).includes('`os-project-manager`'), true); - t('H64 row: …and the field it actually read', row64(text64('card', card18045())).includes('`user.type` = `User`'), true); - t('H64 row: …and names the artefact — a comment by its id', row64(text64('comment', comment5652138683(), carrier64)).includes('comment `5652138683`'), true); - t('H64 row: …a PR as a pull request', row64(text64('pull request', pr18051())).includes('this open pull request'), true); - t('H64 row: …and a card as a card', row64(text64('card', card18045())).includes('this open card'), true); - t('H64 row: it names the SIGNATURE it matched, not merely that one exists', row64(text64('card', card9404())).includes('`Filed by the … seat` / `… dev` header'), true); - t('H64 row: the cost is stated as SUSPENSION, not attribution tidiness', row64(text64('card', card18045())).includes('SUSPENDED'), true); - t('H64 row: the remedy is a re-post through the REST proxy', row64(text64('card', card18045())).includes('re-posts it through the REST proxy'), true); - t('H64 row: …and the original STAYS as history', row64(text64('card', card18045())).includes('original STAYS as history'), true); - t('H64 row: ⛔ report-only — it writes, relabels and re-posts nothing', row64(text64('card', card18045())).includes('writes nothing, relabels nothing and re-posts nothing'), true); - t('H64 row: the clean side is named so a reader knows what good looks like', row64(text64('card', card18045())).includes('`claude[bot]`'), true); - t('H64 row: the boundary is stated as CONSTRUCTION, ⛔ not exemption', row64(text64('card', card18045())).includes('by CONSTRUCTION rather than by exemption'), true); - t('H64 row: …and it says it holds no roster', row64(text64('card', card18045())).includes('holds no roster'), true); - t('H64 row: a second offending comment on one carrier is COUNTED, and the named one is the NEWEST', row64(text64('comment', comment5652138683(), carrier64), 3).includes('3 further comment(s) on this carrier carry the same defect; this is the NEWEST'), true); - t('H64 row: ⛔ no less-than fragment — the sentence is written into a GitHub issue body', /[<>]/.test(row64(text64('card', card18045()))), false); + t('H64 row: it says no session id appears anywhere, which is the finding', row64(claim64()).includes('NO session id appears anywhere in its text'), true); + t('H64 row: it names the SIGNATURE it matched, not merely that one exists', row64(text64('card', card9404({ body: BODY9404_NOID }))).includes('`Filed by the … seat` / `… dev` header'), true); + t('H64 row: …and names the artefact — a comment by its id', row64(claim64()).includes('comment `5652138683`'), true); + t('H64 row: …a PR as a pull request', row64(text64('pull request', pr18051({ body: BODY18051_NOID }))).includes('this open pull request'), true); + t('H64 row: …and a card as a card', row64(text64('card', card9404({ body: BODY9404_NOID }))).includes('this open card'), true); + t('H64 row: it cites the rule by FILE rather than by issue number', row64(claim64()).includes('`.claude/skills/pm-dispatch/SKILL.md`'), true); + t('H64 row: …both halves of it', row64(claim64()).includes('`.claude/skills/pm-dispatch/references/rest-channel.md`'), true); + t('H64 row: the remedy is the artefact\'s own session id', row64(claim64()).includes('gives it its session id'), true); + t('H64 row: …an edit in place is enough where the owner can edit', row64(claim64()).includes('an edit in place is enough'), true); + t('H64 row: …and the original STAYS as history', row64(claim64()).includes('the original STAYS as history'), true); + t('⛔ H64 row: the ACCOUNT is stated NOT to be the repair, so nobody re-posts under another login', row64(claim64()).includes('The ACCOUNT is not the repair'), true); + t('H64 row: the suspension exposure is pointed at the clause rather than re-filed per row', row64(claim64()).includes('reported in the summary clause as INFORMATIONAL'), true); + t('H64 row: ⛔ report-only — it writes, relabels and re-posts nothing', row64(claim64()).includes('writes nothing, relabels nothing and re-posts nothing'), true); + t('H64 row: the boundary is stated as CONSTRUCTION, ⛔ not exemption', row64(claim64()).includes('by CONSTRUCTION rather than by exemption'), true); + t('H64 row: …and it says it holds no roster', row64(claim64()).includes('holds no roster'), true); + t('H64 row: a second offending comment on one carrier is COUNTED, and the named one is the NEWEST', row64(claim64(), 3).includes('3 further comment(s) on this carrier carry the same defect; this is the NEWEST'), true); + t('H64 row: ⛔ no less-than fragment — the sentence is written into a GitHub issue body', /[<>]/.test(row64(claim64())), false); t('H64 row: ⛔ nor in any form\'s description, which the sentence quotes', SEAT_SIGNATURE_FORMS.some((f) => /[<>]/.test(String(f.what))), false); - t('H64 row: not a loud finding — it never escalates a sweep', isLoudFinding(h64UserAuthoredSeatContent(text64('card', card18045()))), false); - t('H64 row: not an UNJUDGED row either — the author WAS read', isUnjudgedFinding(h64UserAuthoredSeatContent(text64('card', card18045()))), false); + t('H64 row: not a loud finding — it never escalates a sweep', isLoudFinding(h64UnattributedSeatContent(claim64())), false); + t('H64 row: not an UNJUDGED row either — the text WAS read', isUnjudgedFinding(h64UnattributedSeatContent(claim64())), false); + + // ── Boundaries: ⛔ no roster, and the two shapes that are out by construction + t('⛔ H64 boundary: the maintainer\'s own prose carries no seat signature and is out', h64UnattributedSeatContent(text64('comment', comment5652138683({ user: user64('hotlong'), body: '同意,按这个方向做。' }), carrier64)), null); + t('H64 boundary: …and the SAME login carrying an unattributed signature DOES fire — the row holds no exemption list', typeof h64UnattributedSeatContent(text64('comment', comment5652138683({ user: user64('hotlong') }), carrier64)), 'string'); + t('⛔ H64 boundary: an approver\'s review text carries no signature either — a `Reviewed-by:` line alone is not the form', h64UnattributedSeatContent(text64('comment', comment5652138683({ user: user64('os-zhuang'), body: 'Reviewed-by: os-zhuang\n\nLooks right to me.' }), carrier64)), null); + t('H64 boundary: …and the same text UNDER the review heading, with no id, is a seat artefact and fires', typeof h64UnattributedSeatContent(text64('comment', comment5652138683({ user: user64('os-zhuang'), body: '## Contract review — PASS\n\nReviewed-by: os-zhuang\n' }), carrier64)), 'string'); + t('H64 boundary: ⛔ the two approver logins appear NOWHERE in this row\'s source-level vocabulary', SEAT_SIGNATURE_FORMS.some((f) => /zhuang|hotlong/.test(String(f.what))), false); - // ── The whole family over a corpus: census, grouping, order and the cap ─── - const legacy64 = (n) => text64('card', card18045({ number: n, created_at: '2026-08-07T15:16:20Z' })); - const fresh64 = (n, at) => text64('card', card18045({ number: n, created_at: at })); + // ── The whole family over a corpus: census, exposure, grouping and the cap ─ const CORPUS64 = [ text64('card', card18045()), text64('card', card9404()), text64('pull request', pr18051()), - text64('comment', comment5652138683(), carrier64), + claim64(), text64('comment', comment5654046782(), carrier64), text64('card', card18045({ number: 1, body: 'ordinary prose with no signature' })), - text64('card', card18045({ number: 2, user: undefined })), - legacy64(3), - legacy64(4), + text64('card', noid64(2, { user: undefined })), + text64('card', noid64(3, { created_at: '2026-08-07T15:16:20Z' })), + text64('card', noid64(4, { created_at: '2026-08-08T09:00:00Z' })), + text64('card', noid64(5)), ]; const sweep64 = h64Sweep(CORPUS64); - t('H64 sweep: every text handed in is counted, signed or not', sweep64.counts.texts, 9); - t('H64 sweep: …the signed ones are separated from the rest', sweep64.counts.signed, 8); - t('H64 sweep: …the user-authored signed ones are the finding population', sweep64.counts.user, 6); + t('H64 sweep: every text handed in is counted, signed or not', sweep64.counts.texts, 10); + t('H64 sweep: …the signed ones are separated from the rest', sweep64.counts.signed, 9); + t('H64 sweep: …and the ones naming no session id are the finding population', sweep64.counts.idless, 5); t('H64 sweep: …of which the pre-pin ones are a CENSUS and file no row', sweep64.counts.legacy, 2); t('H64 sweep: …and the census names the oldest it saw', sweep64.counts.oldest, '2026-08-07T15:16:20Z'); - t('H64 sweep: …the unreadable author is declined and counted, ⛔ never accused', sweep64.counts.unreadAuthor, 1); - t('H64 sweep: …the judged population is what is left', sweep64.counts.judged, 4); - t('H64 sweep: …and the App-authored control is in NONE of those numbers but the first two', sweep64.rows.some((r) => r.message.includes('5654046782')), false); - t('H64 sweep: four rows filed — three bodies and ONE per comment carrier', sweep64.counts.rows, 4); + t('H64 sweep: …the judged population is what is left', sweep64.counts.judged, 3); + t('H64 sweep: three rows filed — two bodies and ONE per comment carrier', sweep64.counts.rows, 3); t('H64 sweep: a comment row is filed against its CARRIER, so the reader lands on the card', sweep64.rows.some((r) => r.subject === carrier64), true); - t('H64 sweep: a body row is filed against the artefact itself', sweep64.rows.some((r) => r.subject.number === 18051), true); + t('H64 sweep: a body row is filed against the artefact itself', sweep64.rows.some((r) => r.subject.number === 5), true); + t('⛔ H64 sweep: the ATTRIBUTED specimens are in the corpus and in NO row', sweep64.rows.some((r) => r.message.includes('18051') || r.message.includes('5654046782')), false); + t('H64 sweep: the exposure half counts every user-authored SIGNED text, attributed or not', sweep64.counts.user, 7); + t('H64 sweep: …and rosters their logins, sorted so the clause is stable run to run', sweep64.counts.logins.join(','), 'os-project-manager,os-tesla'); + t('H64 sweep: …the App-authored one is in the signed count and ⛔ not in the exposure count', sweep64.counts.signed - sweep64.counts.user - sweep64.counts.unreadAuthor, 1); + t('H64 sweep: …the unreadable author is counted, so the exposure number reads as a lower bound', sweep64.counts.unreadAuthor, 1); + t('H64 sweep: …and an unreadable author no longer silences the finding, which is the re-keying', sweep64.rows.some((r) => r.subject.number === 2), true); + t('H64 sweep: the `/pulls` shape is counted as an UNREAD channel, ⛔ never as a PAT', sweep64.counts.userUnreadChannel, 1); + t('H64 sweep: …and no specimen on this corpus wrote with a PAT', sweep64.counts.userPat, 0); + t('H64 sweep: …while a served-and-empty field IS one', h64Sweep([text64('card', noid64(6, { performed_via_github_app: null }))]).counts.userPat, 1); // Grouping: one row per carrier, the NEWEST offender named, the rest counted. const THREAD64 = [ @@ -24288,7 +24510,7 @@ async function selfTest() { // The cap, and the ordering that makes it the right rows. const MANY64 = []; for (let i = 0; i < H64_ROW_CAP + 4; i++) { - MANY64.push(fresh64(19000 + i, `2026-09-13T${String(10 + i).padStart(2, '0')}:00:00Z`)); + MANY64.push(text64('card', noid64(19000 + i, { created_at: `2026-09-13T${String(10 + i).padStart(2, '0')}:00:00Z` }))); } const capped64 = h64Sweep(MANY64); t('H64 cap: a board with more judged findings than the cap files exactly the cap', capped64.counts.rows, H64_ROW_CAP); @@ -24301,14 +24523,30 @@ async function selfTest() { t('H64 sweep: a missing corpus likewise', h64Sweep(undefined).counts.rows, 0); // ── Adjacency: ⛔ this row restates no neighbour's verdict ──────────────── - t('H64 adjacency: H44\'s roster refusal is intact — membership never consults a login', h64SpeaksAbout(text64('card', card18045({ user: user64('someone-nobody-has-heard-of') }))), true); - t('H64 adjacency: …and the same text under an App login leaves the population, which is the whole test', h64SpeaksAbout(text64('card', card18045({ user: APP64 }))), false); + t('H64 adjacency: H44\'s roster refusal is intact — membership never consults a login', h64SpeaksAbout(text64('card', noid64(9404, { user: user64('someone-nobody-has-heard-of') }))), true); + t('H64 adjacency: …and the same text under an App login stays in it too, because the ACCOUNT is not the test', h64SpeaksAbout(text64('card', noid64(9404, { user: APP64 }))), true); t('H64 adjacency: H2 still owns the claim MARKER — this row imports it rather than re-spelling it', CLAIM_COMMENT_MARKER.test(comment5652138683().body), true); t('H64 adjacency: H52 still owns the report marker', OS_DEV_REPORT_MARKER.test('os-dev-report\n{}'), true); t('H64 adjacency: H51 still owns the review heading marker', CONTRACT_REVIEW_HEADING_MARKER.test('## Contract review — PASS'), true); + t('H64 forms: the table is exercised whole — six forms', SEAT_SIGNATURE_FORMS.length, 6); + t('H64 forms: the marker for a claim is the file\'s own, ⛔ not a second spelling', SEAT_SIGNATURE_FORMS[0].test('Claim: x') === CLAIM_COMMENT_MARKER.test('Claim: x'), true); + t('H64 forms: …and the report marker likewise', sig64('os-dev-report\n\n```json\n{}\n```'), 'report'); + t('H64 forms: …and the review form needs BOTH halves', sig64('## Contract review — PASS\n\nReviewed-by: os-zhuang'), 'review'); + t('⛔ H64 forms: …a review HEADING with no `Reviewed-by:` line is not the form', sig64('## Contract review — PASS\n\nLooks fine.'), null); + t('H64 forms: the filing header reads through its measured decorations', sig64('⛔ **Filed by the `domain:cli` execution PM seat** (#6024)'), 'filer'); + t('H64 forms: …and a blockquoted one', sig64('> Filed by the PM seat via the maintainer direct-dispatch channel'), 'filer'); + t('⛔ H64 forms: …but not a mention buried mid-paragraph', sig64('This card was in the end not Filed by the skills seat at all, it was filed by hand.'), null); + t('⛔ H64 forms: …one on the FOURTH line does not read as the session form — a quoted id mid-body is prose', sig64('one\ntwo\nthree\nsession_01DAcomhvR9kKizeYgg89Vo8'), null); + t('H64 forms: …though that body is still ATTRIBUTED, because the id test reads the whole text', seatSessionIdPresent('one\ntwo\nthree\nsession_01DAcomhvR9kKizeYgg89Vo8'), true); + t('⛔ H64 forms: prose containing the word claim is not a claim', sig64('The seat will claim this next round.'), null); + t('⛔ H64 forms: an empty body carries no signature', sig64(''), null); + t('⛔ H64 forms: …and neither does a missing one', sig64(undefined), null); + t('⛔ H64 forms: …and neither carries an id', seatSessionIdPresent(undefined), false); + t('H64 forms: ORDER — the filing header outranks the footer on one body', sig64(`Filed by the skills seat\n\n---\n${FOOTER64}`), 'filer'); + t('H64 forms: …and the claim outranks everything', sig64(`Claim: x\nFiled by the skills seat\n\n---\n${FOOTER64}`), 'claim'); // ── Registry, counters and the clause ──────────────────────────────────── - t('H64 band: registered as a STATE row — two carriers on one live artefact, the repair a re-post', familyBand('H64'), 'state'); + t('H64 band: registered as a STATE row — two carriers on one live artefact, the repair an edit', familyBand('H64'), 'state'); t('H64 band: ⛔ NOT `stall` — this row claims nothing is stopped', familyBand('H64') === 'stall', false); t('H64 band: ⛔ NOT `gate` — both carriers are PRESENT, so no absence reads as a green light', familyBand('H64') === 'gate', false); t('H64 band: ⛔ NOT `inventory` — it alarms about ONE artefact; the population is a census clause', familyBand('H64') === 'inventory', false); @@ -24317,13 +24555,14 @@ async function selfTest() { t('H64 band: …and no band names a family the sweep never emits', familyRegistryCoverage().extra.length, 0); t('H64 band: the registry still fits inside the ledger ROW CAP', Object.keys(HALF_STATE_FAMILY_BAND).length <= FAMILY_LEDGER_ROW_CAP, true); t('H64 band: a gate row still outranks it, so H31/H35 survive the trim longer', familyRank('H31') < familyRank('H64'), true); - t('H64: all eight count keys ride the enumerated forwarding contract', ['seatSignedTexts', 'seatSignedSigned', 'seatSignedUser', 'seatSignedJudged', 'seatSignedLegacy', 'seatSignedOldest', 'seatSignedUnreadAuthor', 'seatSignedRows'].every((k) => SWEEP_COUNT_KEYS.includes(k)), true); + t('H64: all twelve count keys ride the enumerated forwarding contract', ['seatSignedTexts', 'seatSignedSigned', 'seatSignedIdless', 'seatSignedJudged', 'seatSignedLegacy', 'seatSignedOldest', 'seatSignedRows', 'seatSignedUser', 'seatSignedLogins', 'seatSignedUserPat', 'seatSignedUserUnreadChannel', 'seatSignedUnreadAuthor'].every((k) => SWEEP_COUNT_KEYS.includes(k)), true); t('H64 summary: the corpus pair is reported', saidBy('h64SeatSigned', summaryLine({ seatSignedSigned: 197, seatSignedTexts: 526 }, 0)).includes('197 of 526 text(s) read'), true); - t('H64 summary: …and how many of those are user-authored', saidBy('h64SeatSigned', summaryLine({ seatSignedUser: 197 }, 0)).includes('197 of those are authored by a USER account'), true); + t('H64 summary: …and how many of those name no session id', saidBy('h64SeatSigned', summaryLine({ seatSignedIdless: 42 }, 0)).includes('42 of those name no session id anywhere'), true); t('H64 summary: …split into the judged half', saidBy('h64SeatSigned', summaryLine({ seatSignedJudged: 34 }, 0)).includes('34 created on/after'), true); t('H64 summary: …how many were FILED under the cap, so a capped run is visible', saidBy('h64SeatSigned', summaryLine({ seatSignedRows: 10 }, 0)).includes(`10 filed as rows under this family's own ${H64_ROW_CAP}-row cap`), true); t('H64 summary: …and the census half with its reach', saidBy('h64SeatSigned', summaryLine({ seatSignedLegacy: 167, seatSignedOldest: '2026-08-07T15:16:20Z' }, 0)).includes('167 counted here as a CENSUS reaching back to 2026-08-07T15:16:20Z'), true); - t('H64 summary: …the declined authors, which nothing else reports', saidBy('h64SeatSigned', summaryLine({ seatSignedUnreadAuthor: 2 }, 0)).includes('2 signed text(s) carried no readable `user` and were DECLINED'), true); + t('H64 summary: the INFORMATIONAL exposure half rides the same clause, which is the only place it appears', saidBy('h64SeatSigned', summaryLine({ seatSignedUser: 671, seatSignedLogins: ['os-warren'] }, 0)).includes('671 signed text(s) are authored by a USER account rather than `claude[bot]` (`os-warren`)'), true); + t('H64 summary: …the unreadable authors, which nothing else reports', saidBy('h64SeatSigned', summaryLine({ seatSignedUnreadAuthor: 2 }, 0)).includes('2 signed text(s) carried no readable `user`, so the exposure count is a lower bound'), true); t('H64 summary: …that it buys nothing', saidBy('h64SeatSigned', summaryLine({}, 0)).includes('It fetches NOTHING of its own'), true); t('H64 summary: …and that a PR comment thread is outside the corpus, so these are a LOWER BOUND', saidBy('h64SeatSigned', summaryLine({}, 0)).includes('LOWER BOUND'), true); t('H64 summary: the clause renders on EVERY run, not just interesting ones', saidBy('h64SeatSigned', summaryLine({}, 0)).includes('0 of 0'), true);