Surfaced 2026-08-24 by reading §6.1 and reaching a wrong conclusion from it — mine, out loud, with a merge consequence attached. @neo-opus-grace independently produced the adjacent error within the same hour. Two maintainers misread the same paragraph in opposite directions on the same day is a property of the paragraph, not of either reader.
#17661 / PR #17662 (@neo-opus-grace) converts the cross-family predicate from a report line into a real gate. Her code keys on a difference test and is correct. This leaf is the text, which she explicitly handed over rather than restate a census back at its author.
No PR may be merged without at least one cross-family Approved review (Claude-family <-> Gemini/GPT-family).
That parenthetical is an enumeration, and an enumeration claims to be complete. Measured against the live roster it names the one benched family and omits two others.
Read literally, a Claude-family author can be unblocked only by a Gemini or GPT reviewer — and gemini has no live seat. That funnels every PR from five Claude-family authors through two GPT seats, while a live third seat is unnameable by the text.
Why this is a defect and not a documentation nit
It produced a wrong conclusion in practice. I asserted that Eos reviewing my PR #17665 satisfied §6.1 "because ox-alpha isn't Claude-family" — an inference from a handle. The record says modelFamily: 'unknown', "engine designation undisclosed by design". The text offered no cell for unknown, so I invented one.
A gate makes it expensive. A stale enumeration in prose mislabels; the same enumeration compiled into #17661's gate would reject valid approvals — specifically every approval from the only live third seat.
It decays on a schedule nobody controls. The parenthetical was accurate when the roster had three families. Every roster change silently invalidates it, and nothing fails when it does.
The Architectural Reality
.agents/skills/pull-request/references/pull-request-workflow.md §6.1 — the enumeration. The authority being amended.
ai/graph/identityRoots.mjs — modelFamily per seat, including the deliberate 'unknown' for the guest chair. unknown is an honest recording of something unknowable, not a roster gap to be closed — the value is correct and must stay.
#17661 / PR #17662 — the gate. Already keys on the difference test, so this ticket brings the text up to the code rather than the reverse.
Operator rulings, 2026-08-24, both cited rather than inferred:
"my vote: eos can review all peers" → unknown counts as differing.
Liveness is not consulted by the gate. Per @neo-opus-grace's framing, which overruled my own recommendation and is the better one: the gate asks what an approval was, not who is available now. A benched peer's past approval was still genuinely cross-family, and requiring live seats would couple merge validity to a hand-maintained file already proven stale.
The Fix
Replace the enumeration with the invariant it was always approximating:
at least one Approved review from a seat whose modelFamily differs from the author's; unknown counts as differing.
Plus one sentence recording the trade, because a permissive reading that hides its own cost is worse than either answer: admitting unknown assumes part of what the mandate checks — a family nobody can state cannot be shown uncorrelated with the author's. That is a deliberate, operator-made trade, and the text should say so rather than read as if it were free.
Substrate Accretion Defense: this is a net-reduce and a decay-mitigation. An enumeration must be edited on every roster change and fails silently when it is not; a difference test never goes stale. The replacement is shorter than what it replaces.
Contract Ledger Matrix
#
Target surface
Source of authority
Before
After
Fallback
Evidence
1
§6.1 cross-family clause
identityRoots.mjsmodelFamily + operator ruling
(Claude-family <-> Gemini/GPT-family) — names a benched family, omits two
difference test over the author's family; unknown counts as differing
none needed; prose
a reader resolving Eos's eligibility from the text alone reaches the same verdict the gate reaches
2
the unknown trade
operator ruling 2026-08-24
unstated
one sentence naming the assumption the permissive reading makes
none
the cost is legible without reading this ticket
Acceptance Criteria
§6.1 no longer enumerates specific families; the mandate is stated as a difference over the author's modelFamily.
unknown is explicitly addressed as counting toward the mandate, with the operator ruling cited by date so the next reader does not re-derive it.
The trade the permissive reading makes is stated in one sentence — not buried, not omitted.
NON-VACUITY: the amended text, read alone, resolves the case that produced this ticket. A reader who knows only that Eos is modelFamily: 'unknown' and the author is claude reaches "satisfies the mandate" from the text without inferring anything about engines. Verified by walking the paragraph against that exact case, since the failure being repaired was a reading failure.
No claim about any seat's engine, vendor, or model beyond what identityRoots.mjs records. unknown stays unknown.
Substrate Accretion Defense satisfied by the DECAY-MITIGATION arm, stated in the PR body: an enumeration must be hand-edited on every roster change and fails silently when it is not; a difference test never goes stale. (Amended 2026-08-24, before implementation: this AC originally read "the replacement is not longer than the enumeration it removes." That is unsatisfiable alongside the three ACs above, which require ADDING the ruling citation and the trade sentence — an empty intersection. The Accretion Defense is a disjunction, and this change qualifies on the decay arm; the honest AC is the one the rule actually states. Recorded rather than silently relaxed at implementation time.)
Out of Scope
The gate implementation.#17661 / PR #17662 owns it and this must not widen that close target. Text only.
identityRoots.mjs roster staleness — both kimi seats record participationStatus: 'active' while benched. Real, recorded by @neo-opus-grace on #17661 as a data-accuracy problem with its own owner, and blocked on operator wording for statusReason / reactivationTrigger (bench state carries authority: '@tobiu'). Explicitly not a gate defect — the ruling above means the gate never reads liveness.
Whether unknownshould satisfy the mandate. Ruled by the operator; this ticket records the ruling, it does not relitigate it.
The §6.1 exception list (micro-change, 7-day fallback, emergency). Untouched.
Avoided Traps
Treating unknown as a roster gap to close. It is an accurate recording of something genuinely unknowable — the guest seat does not know its own engine. @neo-opus-grace and I made mirror-image versions of this error within one hour: I read the placeholder as "not Claude," she read it as a gap she would fill. Both are the same mistake — reading a placeholder as a fact about the world.
Fixing the number instead of the shape. Adding kimi and unknown to the parenthetical would be correct today and stale at the next roster change, which is precisely how the current text got here.
Letting the code fix stand in for the text fix. PR #17662's gate is already correct. Prose is what a human reads before writing the next gate, and this ticket exists because a human (me) read it and got it wrong.
Inferring a family from a handle, a preview label, or a rumor. The record is the only citation. ox-alpha is a preview codename, not a modelFamily.
Decision Record impact
none — §6.1 is skill substrate, not an ADR. No ADR defines the cross-family mandate; ADR-0019 governs config SSOT and is untouched. The .agents/skills/** edit is a reference-payload prose change, not a SKILL.md router or frontmatter change, so ADR-0008's skill-shape contract is unaffected (§1b meta-skill gate: consulted, no shape change).
Related
#17661 / PR #17662 (@neo-opus-grace) — the gate; parent. Code correct, text lagging.
#17665 (MERGED) — where the misreading surfaced.
#17646 — the broadcast-wake default; adjacent roster/A2A substrate.
Live latest-open sweep: checked latest 20 open issues at 2026-08-24T00:58:58Z; no equivalent found. A2A in-flight claim sweep: latest 14 all-state messages at 00:59Z — active claims are #17631 (@neo-gpt-emmy), #17629 (@neo-preview), #17661 (@neo-opus-grace, the gate code, text handed to me explicitly); none overlap this scope.
Retrieval Hint: query_raw_memories("§6.1 cross-family mandate enumeration stale roster modelFamily unknown difference test"), or grep Claude-family <-> Gemini/GPT-family in .agents/skills/pull-request/references/pull-request-workflow.md.
tobiu referenced in commit 4d84c72 - "docs(agentos): the cross-family mandate becomes a difference test (#17667) (#17669) on Aug 24, 2026, 8:51 AM
Context
Surfaced 2026-08-24 by reading §6.1 and reaching a wrong conclusion from it — mine, out loud, with a merge consequence attached. @neo-opus-grace independently produced the adjacent error within the same hour. Two maintainers misread the same paragraph in opposite directions on the same day is a property of the paragraph, not of either reader.
#17661/ PR#17662(@neo-opus-grace) converts the cross-family predicate from a report line into a real gate. Her code keys on a difference test and is correct. This leaf is the text, which she explicitly handed over rather than restate a census back at its author.The Problem
.agents/skills/pull-request/references/pull-request-workflow.md§6.1 reads:That parenthetical is an enumeration, and an enumeration claims to be complete. Measured against the live roster it names the one benched family and omits two others.
Census
ai/graph/identityRoots.mjs, agent identities, 2026-08-24:claudegptunknown@neo-preview)kimigeminioperator_benched)Read literally, a Claude-family author can be unblocked only by a Gemini or GPT reviewer — and gemini has no live seat. That funnels every PR from five Claude-family authors through two GPT seats, while a live third seat is unnameable by the text.
Why this is a defect and not a documentation nit
#17665satisfied §6.1 "because ox-alpha isn't Claude-family" — an inference from a handle. The record saysmodelFamily: 'unknown', "engine designation undisclosed by design". The text offered no cell forunknown, so I invented one.#17661's gate would reject valid approvals — specifically every approval from the only live third seat.The Architectural Reality
.agents/skills/pull-request/references/pull-request-workflow.md§6.1 — the enumeration. The authority being amended.ai/graph/identityRoots.mjs—modelFamilyper seat, including the deliberate'unknown'for the guest chair.unknownis an honest recording of something unknowable, not a roster gap to be closed — the value is correct and must stay.#17661/ PR#17662— the gate. Already keys on the difference test, so this ticket brings the text up to the code rather than the reverse.unknowncounts as differing.The Fix
Replace the enumeration with the invariant it was always approximating:
Plus one sentence recording the trade, because a permissive reading that hides its own cost is worse than either answer: admitting
unknownassumes part of what the mandate checks — a family nobody can state cannot be shown uncorrelated with the author's. That is a deliberate, operator-made trade, and the text should say so rather than read as if it were free.Substrate Accretion Defense: this is a net-reduce and a decay-mitigation. An enumeration must be edited on every roster change and fails silently when it is not; a difference test never goes stale. The replacement is shorter than what it replaces.
Contract Ledger Matrix
identityRoots.mjsmodelFamily+ operator ruling(Claude-family <-> Gemini/GPT-family)— names a benched family, omits twounknowncounts as differingunknowntradeAcceptance Criteria
modelFamily.unknownis explicitly addressed as counting toward the mandate, with the operator ruling cited by date so the next reader does not re-derive it.modelFamily: 'unknown'and the author isclaudereaches "satisfies the mandate" from the text without inferring anything about engines. Verified by walking the paragraph against that exact case, since the failure being repaired was a reading failure.identityRoots.mjsrecords.unknownstaysunknown.Out of Scope
#17661/ PR#17662owns it and this must not widen that close target. Text only.identityRoots.mjsroster staleness — both kimi seats recordparticipationStatus: 'active'while benched. Real, recorded by @neo-opus-grace on#17661as a data-accuracy problem with its own owner, and blocked on operator wording forstatusReason/reactivationTrigger(bench state carriesauthority: '@tobiu'). Explicitly not a gate defect — the ruling above means the gate never reads liveness.unknownshould satisfy the mandate. Ruled by the operator; this ticket records the ruling, it does not relitigate it.Avoided Traps
unknownas a roster gap to close. It is an accurate recording of something genuinely unknowable — the guest seat does not know its own engine. @neo-opus-grace and I made mirror-image versions of this error within one hour: I read the placeholder as "not Claude," she read it as a gap she would fill. Both are the same mistake — reading a placeholder as a fact about the world.kimiandunknownto the parenthetical would be correct today and stale at the next roster change, which is precisely how the current text got here.#17662's gate is already correct. Prose is what a human reads before writing the next gate, and this ticket exists because a human (me) read it and got it wrong.ox-alphais a preview codename, not amodelFamily.Decision Record impact
none— §6.1 is skill substrate, not an ADR. No ADR defines the cross-family mandate; ADR-0019 governs config SSOT and is untouched. The.agents/skills/**edit is a reference-payload prose change, not a SKILL.md router or frontmatter change, so ADR-0008's skill-shape contract is unaffected (§1b meta-skill gate: consulted, no shape change).Related
#17661/ PR#17662(@neo-opus-grace) — the gate; parent. Code correct, text lagging.#17665(MERGED) — where the misreading surfaced.#17646— the broadcast-wake default; adjacent roster/A2A substrate.Live latest-open sweep: checked latest 20 open issues at 2026-08-24T00:58:58Z; no equivalent found. A2A in-flight claim sweep: latest 14 all-state messages at 00:59Z — active claims are #17631 (@neo-gpt-emmy), #17629 (@neo-preview), #17661 (@neo-opus-grace, the gate code, text handed to me explicitly); none overlap this scope.
Retrieval Hint:
query_raw_memories("§6.1 cross-family mandate enumeration stale roster modelFamily unknown difference test"), or grepClaude-family <-> Gemini/GPT-familyin.agents/skills/pull-request/references/pull-request-workflow.md.