/** * Contract breaks the repository has decided to ship. * * Tier 1's default answer to "this contract cannot be applied over a deployed * one" is to change the pattern, and that answer is right almost every time: a * new required field wants a `Default<>`, not an exemption. But it is not right * every time. A surface can be removed on purpose — the feature behind it is * gone, the pieces holding its state are accepted casualties — and then there * is no pattern change that satisfies the check, because the check is * measuring exactly the decision that was made. * * `--update` cannot express that: it records only when "not recorded" is the * sole finding, so an incompatible contract never reaches a baseline. Deleting * the offending baselines cannot express it either — that is the laundering * `check-baselines-append-only` exists to stop, and it destroys the evidence * that would catch a LATER break against the same contract. So the decision * gets written down here instead, where review sees it as a diff. * * An entry forgives specific `(pattern, baseline)` pairs, and within a pair * only the schema paths it names. Both bounds matter. The pair bound keeps the * exemption from becoming an off switch over time: the contract recorded once * the break ships is a new baseline that no entry names, so the very next * change to that pattern is gated again, against the shape the break left * behind. The path bound keeps it from becoming one within a single change: the * compatibility proof reports every issue it finds against a baseline, each * blaming one path, so forgiving by pair alone would suppress an unintended * break that happened to land beside the accepted one — and `--update` would * then record that broken contract as the new baseline. * * Paths are written exactly as the proof names them (`result.crossrefs`, * `argument.topics[]`), and an entry names exactly the paths its pairs blame. * A named path that none of them blames would forgive a later break at that * path against those baselines, including the one recorded just before the * break, which is where an unintended second break in the same change is * judged. * * The list can only shrink. A listed pair that no longer produces a finding — * because the pattern grew the surface back, or the baseline is gone — fails * the run, and so does a named path that none of the entry's pairs blames, so * an exemption cannot outlive the break it was granted for. */ export interface AcceptedContractBreak { /** Pattern key: the path relative to `packages/patterns`. */ pattern: string; /** Baseline labels (filename stems) this pattern may fail to apply over. */ baselines: readonly string[]; /** * Schema paths this break may blame, spelled as the compatibility proof * spells them. A finding blaming anything else stands, and a path none of * the entry's pairs blames fails the run. */ paths: readonly string[]; /** Why the break was accepted. */ reason: string; /** * Repo-relative path of the decision record under `docs/history/` — the * deliberation behind this entry's declaration. Its existence is enforced * when either gate runs (`pattern-break-registry-guards.ts`). */ record: string; /** * The ruling that lets this entry name a required pattern. Absent on every * other entry: the guard refuses a break on an auto-updating root unless * one is carried, because such a break strands every space's root the * moment it merges, and that is a decision a person makes by name. */ requiredPatternOverride?: RequiredPatternOverride; } /** Who ruled that a required pattern takes an accepted break, and why. */ export interface RequiredPatternOverride { /** The person whose ruling this is. */ rulingBy: string; /** The date of the ruling, `YYYY-MM-DD`. */ on: string; /** The ruling, quoted or summarized. */ reason: string; } export const ACCEPTED_CONTRACT_BREAKS: readonly AcceptedContractBreak[] = [ { // The profile gained its owner-protected share inbox pointer (`inbox`, // optional, undefaulted). The picker consumes a stored profile, and the // proof compares the new property's `ifc` label against a baseline that // has no such property at all, so it reads a label change where a // stored profile without the field still validates. An unlabelled // pointer would pass the proof and let a stranger redirect the owner's // inbox; the label is the point. pattern: "system/profile-picker.tsx", baselines: [ "20260729T022742Z-BVxqS5A3M24IcX6m", "20260818T220011Z-J-y30yE6xQ8axACi", ], paths: ["argument.defaultProfile"], reason: "the profile's new owner-protected inbox pointer reads as a changed label under a baseline that never had the property", record: "docs/history/profile-inbox-pointer-break.md", }, { // A SECOND entry for the picker, and no baseline here appears above: the // pairs stay disjoint because the gate keys accepted pairs into a Map, // so a baseline named twice would take the later path set in place of // the earlier one. // // The share inbox pointer's `space` and `host` fields left, replaced by // a link to the inbox piece under `piece`. The recorded object requires // the two fields, so no candidate without them applies over it. pattern: "system/profile-picker.tsx", baselines: [ "20260915T064957Z-Idjl03Ljo7Yyeecn", "20260918T000350Z-TY78mWqtLnHDoZtN", ], paths: ["argument.defaultProfile"], reason: "the share inbox pointer's `space` and `host` fields left, replaced by a link to the inbox piece under `piece`, which the recorded object requires them beside", record: "docs/history/profile-inbox-piece-break.md", }, { // The record's scope moved from the value onto the handle once the schema // generator stopped dropping a scope wrapper reached through an alias. The // recorded contracts carry no scope at all; the argument now caps the // handle at `user`, which every record the `agent` builtin creates meets. // These two baselines also predate `INVALID_RESULT` in the run's error // taxonomy, and the proof blames both paths in one finding, so this entry // names both; `agent-run-invalid-result-error-code-break.md` records the // second. pattern: "system/agent-run.tsx", baselines: [ "20260920T164352Z-nTSuqgfjRzkwXIgf", "20260920T170445Z-TMoN6scQaXVlTvPW", ], paths: ["argument.run", "result.run.errorCode"], reason: "the run argument's scope moved onto the handle as a user cap, which the recorded unscoped contracts read as a changed asCell entry; the linked records are user-scoped documents the cap admits", record: "docs/history/agent-run-record-handle-scope-break.md", }, { // A run's error taxonomy gained `INVALID_RESULT`, a value no recorded // reader of the result has seen. Every reader shows the code as text. The // entry above covers the two earlier baselines, whose finding also blames // `argument.run`. pattern: "system/agent-run.tsx", baselines: [ "20260922T054240Z-8--YFk9i7OyiTc6X", ], paths: ["result.run.errorCode"], reason: "a run's errorCode gained INVALID_RESULT for a completed model loop whose result fails its schema; no stored record holds it until a runner reports one, and every reader shows the code as text", record: "docs/history/agent-run-invalid-result-error-code-break.md", }, { // The same ruling seen from the profile itself: both fields that left, // in the pointer it publishes and in the event `setInbox` takes. pattern: "system/profile-home.tsx", baselines: [ "20260915T064957Z-mE7S34E5xl20_PZs", "20260917T235321Z--A47I2nujs7eKua6", ], paths: [ "result.inbox.host", "result.inbox.space", "result.setInbox.host", "result.setInbox.space", ], reason: "the share inbox pointer's `space` and `host` fields left, replaced by a link to the inbox piece under `piece`, which the recorded object requires them beside", record: "docs/history/profile-inbox-piece-break.md", }, { // The same ruling seen from home, whose published `defaultProfile` // carries the profile's shape. Home is a required pattern, so this entry // carries the ruling that lets it name one: every space's root takes the // break the moment it merges, and nothing deployed beyond one install // holds a pointer of the old shape. pattern: "system/home.tsx", baselines: [ "20260915T064957Z-k40oHeJO0hh31i1H", "20260917T220636Z-xdDxE87ojM-_6i1g", "20260918T000350Z-AhP3Iq9N0OLx48b1", "20260918T002421Z-RB590FUNua-vIXOh", "20260918T072634Z-NeP8mB1oe_0bWKFV", ], paths: [ "result.defaultProfile", "result.mru[].inbox.host", "result.mru[].inbox.space", "result.mru[].setInbox.host", "result.mru[].setInbox.space", "result.profiles[].inbox.host", "result.profiles[].inbox.space", "result.profiles[].setInbox.host", "result.profiles[].setInbox.space", ], reason: "the share inbox pointer's `space` and `host` fields left, replaced by a link to the inbox piece under `piece`, which the recorded object requires them beside", record: "docs/history/profile-inbox-piece-break.md", requiredPatternOverride: { rulingBy: "Berni", on: "2026-09-18", reason: "you can make that an allowed incompatible pattern update if you need to since other than Gideon no one will have that version of setInbox", }, }, { // Three cells' declared defaults take effect. Each is typed // `Stored | Default>` and reaches the schema // generator through a scope alias, where default recovery from the // resolved union had taken the propertyless plain arm for a marker-less // brand, so no baseline carries the `default: {}` the declarations always // meant. A piece holding one of them unset reads `{}` where it read // `undefined`. pattern: "cfc-group-chat-demo/main.tsx", baselines: [ "20260729T022742Z-piF14M8QDh5pSPw1", "20260821T064855Z-7vNcdzNpQKWFJXVr", "20260831T222745Z-kIL5Ew24PVUYtyxy", ], paths: [ "argument.adminRegistry", "result.adminRegistry", "argument.myProfile", "result.myProfile", "argument.rooms", "result.rooms", "result.profileDraft", "result.messageDraft", "result.hostMessageDraft", "result.roomDraft", "result.setProfileDraft", "result.setMessageDraft", "result.setHostMessageDraft", "result.setRoomDraft", "result.saveProfile", "result.sendTrustedMessage", "result.addTrustedRoom", "result.hostLookalikeSend", ], reason: "the declared `Default<{}>` of the admin registry, the profile, and the room list is honored where the recorded contracts carry no default" + "; and the drafts removed, with the trusted streams taking the text a " + "`cf-submit-input` click carries (docs/history/cfc-chat-demo-submit-input-break.md)", record: "docs/history/admin-registry-default-honored-break.md", }, { // The Join verb's event opens: `Record` compiled to // a closed empty object the runner's closed-world gate now enforces, so // the rendered button's serialized DOM event was refused and the roster // could never be joined. `void` (the lobby's shape) is a different // recorded contract for the stream; nothing held state under the old one. pattern: "profile-roster-live-demo.tsx", baselines: ["20260729T022742Z-QNOFVBAs80X9XKZu"], paths: ["result.join"], reason: "the Join verb's closed empty event refused every rendered click; re-declared void", record: "docs/history/roster-join-event-opened.md", }, { // The same break in the shared roster, same record. pattern: "shared-profile-roster/main.tsx", baselines: ["20260729T022742Z-MLeLOCqjpbIUoIib"], paths: ["result.join"], reason: "the Join verb's closed empty event refused every rendered click; re-declared void", record: "docs/history/roster-join-event-opened.md", }, { // One entry per (pattern, BASELINE) pair, and that is a requirement // rather than tidiness: the gate keys accepted pairs into a Map, so a // second entry naming a baseline this one also names REPLACES its path // set rather than adding to it. Breaks that share baselines therefore // share an entry — and its single `record`, the other break named in // the reason — while a later break against baselines no earlier entry // names gets its own entry, with the pairs kept disjoint. // // Carried here: the reference graph rebuilt on cell identity, and the // board's demand narrowed to the eight members it reads — which narrows // the published projection with it, opens the link and author `kind` // domains a closed enum in provided data could never widen, and stops // `addLink` requiring the two fields its handler already defaulted. pattern: "topics/main.tsx", baselines: [ "20260729T022742Z-31DT95VXuyOj8JeU", "20260803T191013Z-jUl4tnb6Dw8LBVJj", "20260804T003803Z-4eh5RiQl5phB1jpX", "20260806T230301Z-96vyQcPJ2htEfat9", "20260807T155936Z-wBGKcf6ruadhes3g", "20260807T190842Z-SD0Ii3eK0ZnJnIhs", "20260810T212206Z-cIIz70jbLbbPc-F3", "20260812T003521Z-Jy37T5qk4KSHkgQe", "20260814T233350Z-jHoJZsDa5eUdWU-B", "20260817T051200Z-NIE10ssgY89CXloq", "20260817T212730Z-3FUPLp4oeb7gwpch", "20260817T231646Z-3OsO1miQLNSxm34N", "20260818T002831Z-Lk1mtrXcWtEV2FAK", "20260818T020120Z-AfZn709Q7YVH7WlZ", "20260819T172917Z-ocrU646RD4YKITBc", ], paths: [ "result.mentionable[].mention", "result.crossrefs[].fid", "result.crossrefs[].commentCount", "result.index[].fid", "result.index[].createdBy", "result.mentionable[].addComment", // The unsigned caller retires: `agentName` is required on every verb, and the display-name mirrors that path filled go with it. "result.myName", "result.crossrefs[].topic", "result.mentionable[].crossrefs", "result.mentionable[].links", "result.topics[].addComment", "result.topics[].crossrefs", "result.topics[].links", "result.topics[].createdBy", "result.index[].topic", "result.crossrefs[].title", "result.topics[].mention", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.setMyName", "result.addTopic.agentName", "result.crossrefs[].referencedBy", "result.crossrefs[].refsOut", "result.mentionable[].addLink", "result.mentionable[].body", "result.mentionable[].bodyUpdatedAt", "result.mentionable[].bodyUpdatedBy", "result.mentionable[].commentCount", "result.mentionable[].comments", "result.mentionable[].createdAt", "result.mentionable[].createdBy", "result.mentionable[].createdByName", "result.mentionable[].lastActivityAt", "result.mentionable[].setBody", "result.topics[].addLink", "result.topics[].bodyUpdatedAt", "result.topics[].bodyUpdatedBy", "result.topics[].comments", "result.topics[].createdByName", "result.topics[].setBody", "result.index[].referencedBy", "result.index[].refsOut", "result.index[].commentCount", "result.index[].lastActivityAt", "result.crossrefs[].createdAt", "result.crossrefs[].createdBy", "result.crossrefs[].lastActivityAt", "result.crossrefs[].referencedByLinks", "result.crossrefs[].refsOutLinks", "result.mentionable[].mentioned", "result.mentionable[].mentions", "result.mentionable[].referencedBy", "result.mentionable[].references", "result.mentionable[].unmention", "result.topics[].mentioned", "result.topics[].referencedBy", "result.topics[].references", "result.topics[].unmention", ], reason: "Two accepted breaks on one pattern: the reference-graph rebuild on cell " + "identity (docs/history/topics-crossref-identity-break.md), and the " + "demand narrowing recorded below." + " The further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md.", record: "docs/history/topics-demand-narrowing-break.md", }, { // A SECOND entry for this pattern, deliberately: the one-entry rule the // neighbors state guards against two entries naming the SAME baseline — // the gate's Map keeps one path set and drops the other — and no // baseline here appears above. Keeping the pairs disjoint is what keeps // the bound tight: forgiving this path on the older baselines too would // forgive a later break at it against pairs this break never produced a // finding against. pattern: "topics/main.tsx", baselines: [ "20260826T221814Z-pt-HCeVbN-iyz9VX", "20260831T174843Z-iQFp3QQPN2zAkRuJ", ], paths: [ // The published mention universe stopped carrying the topics' own // surface: a row is two strings and an unread `piece` reference, // because every field a row carries by value ships to every reader // of the universe. "result.mentionable[].body", "result.mentionable[].mentions", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.mentionable[].commentCount", "result.mentionable[].createdAt", "result.mentionable[].createdBy", "result.mentionable[].lastActivityAt", ], reason: "The board's mention universe became a derived index of two-string " + "rows holding each topic as an unread reference, so the published " + "`mentionable` stopped carrying a topic's own surface. Wired to the " + "raw topics list it multiplied every topic's resume into every " + "sibling topic under document-granular delivery." + " The further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md.", record: "docs/history/topics-mentionable-index-break.md", }, { // One entry per (pattern, BASELINE) pair, and that is a requirement // rather than tidiness: the gate keys accepted pairs into a Map, so a // second entry naming a baseline this one also names REPLACES its path // set rather than adding to it. Breaks that share baselines therefore // share an entry — and its single `record`, the other break named in // the reason — while a later break against baselines no earlier entry // names gets its own entry, with the pairs kept disjoint. // // Carried here: the reference graph rebuilt on cell identity, and the // board's demand narrowed to the eight members it reads — which narrows // the published projection with it, opens the link and author `kind` // domains a closed enum in provided data could never widen, and stops // `addLink` requiring the two fields its handler already defaulted. And // the mention universe reaching a topic as a readable cell, the break // the entry below records for the baselines after these. pattern: "topics/topic.tsx", baselines: [ "20260729T022742Z-6pmDbdEVBz84jJRa", "20260804T003803Z-I2QhJWkighYF1Fa1", "20260806T230301Z-JAM7epNCGeRRdbAJ", "20260807T155937Z-T6UB0k9yc-pCo6Fj", "20260807T190842Z-XNG2XTMFFTjcmnX0", "20260808T001558Z-H7ntBZnGU80t30LL", "20260810T212206Z-FQasUmU3p-SDapLo", "20260812T003521Z-XWPlA9Dl3OHXlHEH", "20260814T233350Z-ignmxWvAy2vygaDl", "20260817T212731Z-S2Y3ePoq7Zj_7fLa", "20260817T231646Z-bBfPByCuBScHp-Ou", "20260818T002831Z-ULPZkKYbQEmzLpDl", "20260818T020121Z-Y5Q-u4fiTKGUrP5Y", "20260819T172917Z-K_8fL8hZtM4xYV7V", ], paths: [ "argument.boardCrossrefs", "result.crossrefs", "result.addLink.kind", // The unsigned caller retires: a comment always carries a structured author now, so the mirror beside it goes. "result.createdByName", // The mention universe's readable-cell narrowing, the break the entry // below records: these baselines carry it as well, and the argument // role reports it once the widened `kind` domains are accepted (a // closed enum widening to `string` is a type widening the proof // admits). "argument.mentionable", "result.createdBy", "result.referencedBy[].createdBy", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.addComment.agentName", "result.addLink.agentName", "result.bodyUpdatedBy", "result.comments[].authorName", "result.comments[].author.kind", "result.linkKindDraft", "result.links[].addedBy.kind", "result.links[].kind", "result.setBody.agentName", "result.titleUpdatedBy", ], reason: "Three accepted breaks on one pattern: the reference-graph rebuild on " + "cell identity (docs/history/topics-crossref-identity-break.md), the " + "demand narrowing recorded below, and the mention universe's readable-" + "cell narrowing, which these baselines carry as well " + "(docs/history/topics-mentionable-readonly-break.md)." + " The further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md.", record: "docs/history/topics-demand-narrowing-break.md", }, { // The parking coordinator's admin roster declared a `requiredIntegrity` // floor that nothing in the pattern could satisfy: no `addIntegrity` mint // on the roster path, and the roles' own mint does not reach the path the // floor sits on. Under `cfcWriteFloor: "enforce"` every write to the // roster is refused, so the floor had to gain the mint that satisfies it, // and the roster had to name the same atom the spot list is floored on — // a write may only consume reads that all carry one witness for its floor, // and checking a spot write reads the roster. The floor also gained a // `writeAuthorizedBy` binding, so the roster is written by one reviewed // handler rather than by any action that happens to hold the cell. pattern: "factory-outputs/parking-coordinator/main.tsx", baselines: [ "20260729T022742Z-ZaBTuPX0s1ITifoj", "20260804T003803Z-xkP59lcpdOUTy_M1", ], // `ifc` is compared for exact equality, so any correction to an // unsatisfiable floor reads as a break. Both roles name the same one // path: the roster's own. paths: [ "argument.adminRegistry.admins", "result.adminRegistry.admins", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.togglePersonAdmin.name", ], reason: "The admin roster's integrity floor was unsatisfiable, so no write to " + "it could be accepted once the write floor is enforced. Correcting the " + "declaration changes the `ifc` at that path, which no shape of the " + "pattern avoids. A piece holding a roster keeps its stored roles; what " + "it loses is the ability to be updated in place to the corrected " + "contract." + " The further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md.", record: "docs/history/parking-admin-floor-contract-break.md", }, { // Lot Watch's admin roster declared a `requiredIntegrity` floor nothing // could satisfy: no `addIntegrity` mint on the roster path, and a floor // atom that differed from the one its roles carry, so the roster read a // roster change has to make could never witness the floor either. Under // `cfcWriteFloor: "enforce"` every write to the roster is refused. The // declaration gained the mint, the single `lot-watch-admin` atom, and a // `writeAuthorizedBy` binding naming the one handler that may write it, // so the roster is no longer written by any action that holds the cell. pattern: "factory-outputs/lot-watch/main.tsx", baselines: [ "20260729T022742Z-W-iDVp0QJ9fPJBsi", "20260804T003803Z-MtNQDxsoMJZjryZC", ], // `ifc` is compared for exact equality, so any correction to an // unsatisfiable floor reads as a break. The registry is not published in // the result, so only the argument role names the roster's own path. paths: ["argument.adminRegistry.admins"], reason: "The admin roster's integrity floor was unsatisfiable, so no write to " + "it could be accepted once the write floor is enforced. Correcting the " + "declaration changes the `ifc` at that path, which no shape of the " + "pattern avoids. A piece holding a roster keeps its stored roles; what " + "it loses is the ability to be updated in place to the corrected " + "contract.", record: "docs/history/lot-watch-admin-floor-contract-break.md", }, { // The lunch poll's identity moved from display names to profile cells // (see docs/history/lunch-poll-identity-break.md). The proof reports two // paths here: the published name-keyed admin result went away, and the // visit array's legacy roster links were replaced by optional profile // links. Cell metadata is stable under default insertion, so the proof // identifies the incompatible link at `loggedBy`. The // vintage replay still preserves the stored visit rows. pattern: "lunch-poll/main.tsx", baselines: ["20260729T022742Z-5bjUubcOZ-gpvz7F"], paths: [ "argument.visits[].loggedBy", "result.adminName", "result.joinAs.name", "result.todaysVotes[].voterName", "result.votes[].voterName", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.participantProfiles", "result.recentVisits[].loggedBy", "result.recentVisits[].votes[].voterLink", ], reason: "Lunch-poll identity moved from display names to profile cells. " + "The published `adminName` result cannot survive the removal of " + "name-keyed identity; `argument.visits[].loggedBy` identifies the " + "legacy roster link that became an optional profile link. The vintage " + "replay preserves those rows, but the root argument contract cannot " + "be updated in place." + " The further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md.", record: "docs/history/lunch-poll-identity-break.md", }, { // Same decision, seen from the join card. The removed optional admin input // is compatible; the checker exemption is only for `me`, which published // the viewer's display name as identity. Joined-ness and host status are // now derived from profile-cell comparison. pattern: "lunch-poll/participant-identity-card.tsx", baselines: ["20260729T022742Z-KMaq_J9475tWtRxW"], paths: [ "result.me", "result.joinAs.name", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.profileName", ], reason: "Lunch-poll identity moved from display names to profile cells. " + "The card's published `me` result treated the viewer's display name as " + "identity, so it goes with the model it keyed." + " The further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md.", record: "docs/history/lunch-poll-identity-break.md", }, { pattern: "agent-sessions-debug/main.tsx", baselines: ["20260818T001423Z-_DSuxwZWgUTcB_2z"], // The proof reports `ownerDid` first. Holding it compatible in a separate // proof reports the command cell's change from an optional opaque input to // the required writable queue that the connector host supplies. paths: ["argument.ownerDid", "argument.commandsCell"], reason: "Before its first deployment, the connector-managed debug view changed " + "to require the host's configured owner DID and one authoritative, " + "writable command queue. The owner isolates discovery and commands in " + "a shared space, while the writable queue is the host's protected " + "command input. The earlier contract was not deployed, and neither " + "input has a safe compatibility default.", record: "docs/history/agent-connector-owner-identity-break.md", }, { // A parking-admin role named a person by name. Review asked for the CFC // primitives instead — compare profiles by their cells, not by what those // cells are called — so a role names the viewer's `#profile` cell, and the // stored shape of a role changed with it. pattern: "factory-outputs/parking-coordinator/main.tsx", baselines: [ "20260820T191154Z-Fah23u1z5LYk4qKk", "20260825T211621Z-wEoO6wvf7g-fhtJd", ], // The same change seen from the two roles a contract has: the subject is a // cell where it was an inline object, and the name inside it goes with it. paths: [ "argument.adminRegistry.admins[].subject", "result.adminRegistry.admins[].subject.personName", "result.togglePersonAdmin.name", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.togglePersonAdmin.newName", ], reason: "A role's subject moved from a person's name to their profile cell, so " + "authority is compared by identity rather than by a string. A stored " + "role of the old shape names nobody the pattern can resolve, and the " + "piece holding it keeps running its own source; a space starting over " + "on the new contract recovers through the same open-roster bootstrap " + "that lets a fresh space have an admin at all." + " The further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md.", record: "docs/history/parking-admin-profile-subject-break.md", }, { // The exemplar's index rows became the members themselves. A row's own // address is the item's address, so nothing in a row carries a separate // reference to it; and a row reads the board's name for its item out of // the item's own `shortName`, so the demand carries that member too. pattern: "collection-naming/board.tsx", baselines: [ "20260904T001531Z-WRSzkgeFJQmQt1ZM", "20260904T022635Z-OsLnrwxWR4PfC0gG", ], // The ruling seen from the published row, which lost the reference the // derived row document carried. paths: [ "result.index[].member", "result.index[].name", ], reason: "An index row IS the member, so the derived row document's `member` " + "reference is what the ruling removed, and no shape of the board both " + "keeps it and makes a row the member. The row demand's `shortName` " + "needs its `| undefined` arm, without which the pattern compiler " + "refuses the board where an item meets the row type, and that arm moves " + "the demand's defaults below a constraint the proof cannot prove stable " + "under default insertion. The exemplar had no instance beyond a " + "throwaway local demo, so no piece held the contract this replaces.", record: "docs/history/collection-naming-index-rows-break.md", }, { // A second entry for this pattern, with baselines disjoint from the other // one's: the gate keys accepted pairs into a Map, so a baseline named // twice would take the later path set in place of the earlier one. The // older baselines report this same narrowing for the argument role and // name it in their own entry above, beside the breaks only they carry. pattern: "topics/topic.tsx", baselines: [ "20260826T221814Z-RZiIzB74VkCoXYty", "20260831T181712Z-hoTDhhCHJzB2Umnc", "20260831T204059Z-2Fi9qBnr1mK4_p2J", "20260901T191235Z-4uo6zrdZRahgZ98O", "20260905T021503Z-Y-lXQUSup41JBSeM", "20260906T050633Z-d6Et9xqrHqjlhlzA", ], // One path, and only in the argument role: the element type is untouched, // so `asCell` at the mention universe's own node is the whole break. paths: ["argument.mentionable"], reason: "The board's mention universe reaches a topic as a readable cell rather " + "than a writable one, so the retained link's proof drops the write-back " + "leg that refused a topic its own bytes. `asCell` is compared for exact " + "equality, so narrowing a cell reads as a break however narrow the " + "narrowing is. The one shape that keeps the writable handle instead " + "declares the board's `piece` on the topic's projection, which is the " + "wide demand the narrow one was adopted to avoid. A deployed topic takes " + "this one update forced and is proven again on every update after it.", record: "docs/history/topics-mentionable-readonly-break.md", }, { // A SECOND entry for this pattern, and no baseline here appears above: // the pairs stay disjoint so that the older ones, which predate // `shortName` entirely, keep the tight bound the entry above gave them. // // The exemplar's `shortName` takes the spelling Topics ships, // `shortName?: string`. One property in two roles here, because a row IS // the item: the board's demand of a stored item, and the row the board // publishes. pattern: "collection-naming/board.tsx", baselines: [ "20260904T051612Z-5rtP1U2c-e31PtKt", "20260904T063417Z-pWfbKiYw-7bd7xpC", "20260905T003604Z-uX940wR7R4lVwuOt", ], // The one spelling seen from the two roles a contract has: an optional // property carries no default, so the demand's defaults move, and the // published row stops requiring the name. Stable cell metadata lets the // proof identify the incompatible type at `shortName`. paths: [ "argument.items[].shortName", "result.index[].shortName", "result.items[].shortName", ], reason: "The exemplar exists to prove a contract before it is grafted onto " + "Topics, and on this property it proved a spelling Topics does not " + "ship. Aligning it makes the demand's defaults move and drops the " + "published row's requirement, neither of which any shape of the board " + "avoids while the property is optional. The exemplar has no " + "deployment, so no piece holds the contract this replaces.", record: "docs/history/collection-naming-shortname-spelling-break.md", }, { // The member's side of the same alignment: an item publishes its name the // way a topic does, and demands it of a universe entry the same way. pattern: "collection-naming/item.tsx", baselines: [ "20260904T001531Z-z0Gy14PpefRML1fx", "20260904T022635Z-GMG883UMGFeAnh-r", ], // These two baselines predate the item's mention universe, so the // published name is the whole of what they blame. paths: ["result.shortName"], reason: "An item publishes `shortName` as `shortName?: string`, the spelling " + "Topics ships, where it published a required property whose type " + "admitted `undefined`. The published property stops being required, " + "which no shape of the item avoids while it is optional. The exemplar " + "has no deployment, so no piece holds the contract this replaces.", record: "docs/history/collection-naming-shortname-spelling-break.md", }, { // A second entry for the item, keeping its pairs disjoint from the two // above for the reason the board's pair of entries states. // // Carried here: the `shortName` alignment recorded in the entry above, // and the mention universe becoming a readable binding — the two // breaks land on the same baselines, which is what puts them in one // entry. pattern: "collection-naming/item.tsx", baselines: [ "20260904T082808Z-1fwb7SfgxGYK3VR0", "20260905T003605Z-gslMTuThImQHhkVQ", ], // These two carry the mention universe, which is what makes them the // pairs both breaks blame. `asCell` is compared for exact equality, so // the readable binding is reported at the whole property rather than at // an element of it, and it is reported ahead of the defaults the // optional `shortName` moves. paths: [ "argument.mentionable", "result.shortName", ], reason: "Two accepted breaks on one pattern. An item publishes `shortName` as " + "`shortName?: string`, the spelling Topics ships, and demands it of a " + "universe entry the same way " + "(docs/history/collection-naming-shortname-spelling-break.md). And " + "the universe binding became readable, recorded below. Neither has a " + "shape of the item that avoids the break, and the exemplar has no " + "deployment, so no piece holds the contract they replace.", record: "docs/history/collection-naming-mentionable-readonly-break.md", }, { // Two entries, one per pattern, for one ruling: `LLMMessageSchema` stopped // admitting the `system` role, and that schema reaches the argument // contract of every pattern whose `messages` it types. pattern: "chatbot.tsx", baselines: [ "20260729T022742Z-Wx_o-CaAUThcJygl", "20260818T183826Z-ibsxlvix5LQH7bfY", ], paths: [ "argument.messages[].role", ], reason: "A system instruction travels in the request's `system` field. The " + "guard the toolshed route gates on refused a system-role message " + "already, and behind it the AI SDK refuses one inside `messages` " + "whatever its content, so the role named a message no piece could ever " + "send. An enum in a deployed contract cannot stop accepting a value " + "compatibly, and no shape of the schema both drops the role and applies " + "over a baseline declaring it. The narrowing strands nothing: the " + "runtime enforces an enum neither on read nor on write, so a stored " + "system-role message materializes under the new contract unchanged.", record: "docs/history/features/llm-message-role-narrowing-break.md", }, { // The second pattern of the same ruling. Its baseline appears in no other // entry, so the pairs stay disjoint. pattern: "deep-research.tsx", baselines: [ "20260729T022742Z-6PInVAlNOHThJNGH", ], paths: [ "argument.messages[].role", ], reason: "The `system` role leaving `LLMMessageSchema`, recorded once for both " + "patterns it breaks.", record: "docs/history/features/llm-message-role-narrowing-break.md", }, { // A pattern's result schema no longer carries the least upper bound of // its argument schema's `ifc.confidentiality` at its root. That clause was // a dependency measurement written into the component CFC §8.12.8 reserves // for declared store policy, and at a document root it covers every field, // `$UI` included — which is what denied the whole rendered sub-view of any // pattern holding a confidential argument. The author's own per-field // declarations are untouched. pattern: "budget-tracker/confidential.tsx", baselines: [ "20260818T045519Z-gy2rtE24CYfgovy8", ], // `ifc` is compared for exact equality, so dropping the synthesized clause // reads as a break. It sat at the result root, which the proof names as // the whole role. paths: [ "result", ], reason: "The builder synthesized a covering confidentiality clause at the " + "result schema's root from the argument schema's shape, measuring no " + "transaction. Stored, it labels every field of the result document, so " + "the display ceiling denies the pattern's entire view. No shape of the " + "pattern avoids the change: the clause came from the builder rather " + "than from the source. A deployed piece keeps its stored labels, which " + "are grow-only; what it loses is the ability to be updated in place " + "onto the narrowed contract.", record: "docs/history/pattern-result-ifc-contract-break.md", }, { // The second pattern of the same ruling. Its baseline appears in no other // entry, so the pairs stay disjoint. pattern: "cfc-input-cell-demo/briefing.tsx", baselines: [ "20260828T041445Z-xK1PX5XOqtJknIj6", ], paths: [ "result", ], reason: "The synthesized result-root confidentiality clause leaving the " + "builder, recorded once for all three patterns it breaks. This one " + "exists to show that its two results carry different labels, which a " + "clause on the object containing them contradicted.", record: "docs/history/pattern-result-ifc-contract-break.md", }, { // The third pattern of the same ruling. pattern: "cfc-input-cell-demo/seed.tsx", baselines: [ "20260828T041445Z-77e4kMM67vF8OWFf", ], paths: [ "result", ], reason: "The synthesized result-root confidentiality clause leaving the " + "builder, recorded once for all three patterns it breaks. This one " + "seeds one labeled cell beside one unlabeled cell, which a clause over " + "both defeated.", record: "docs/history/pattern-result-ifc-contract-break.md", }, { // The Send verb's event opens, the same break the roster Join verbs took // above: `Record` compiled to a closed empty object, // which the runner's closed-world gate enforces, so the Send button's // serialized DOM event was refused and no message could be sent. `void` // is a different recorded contract for the stream; nothing held state // under the old one. pattern: "profile-group-chat/main.tsx", baselines: ["20260729T022742Z-VIR19UFKyKrauX_B"], paths: ["result.sendMessage"], reason: "the Send verb's closed empty event refused every rendered click; re-declared void", record: "docs/history/chat-send-event-opened.md", }, { // The same break in the scoped chat, same record. pattern: "scoped-group-chat/main-plain-inputs.tsx", baselines: [ "20260729T022742Z-Z-pkp9K1p6P_byR_", "20260909T184756Z-M530BSuyTtIuZ_9J", ], paths: ["result.sendMessage"], reason: "the Send verb's closed empty event refused every rendered click; re-declared void", record: "docs/history/chat-send-event-opened.md", }, { // The same break in the scoped chat's writable-input variant, same record. pattern: "scoped-group-chat/main-with-writable-inputs.tsx", baselines: [ "20260729T022742Z-_XyScfA2QEj14JnS", "20260909T184756Z-NMt89YDsQnt_urES", ], paths: ["result.sendMessage"], reason: "the Send verb's closed empty event refused every rendered click; re-declared void", record: "docs/history/chat-send-event-opened.md", }, { // The everyone-is-admin flag's `true` branch gains the `writeAuthorizedBy` // claim its type declares, which a canonical alias formatting its payload // without a node had dropped. The proof descends to the flag here. pattern: "cfc-group-chat-demo/main.tsx", baselines: ["20260922T020444Z-IRoEgfpuUdf-xwvE"], paths: [ "argument.adminRegistry.everyoneIsAdmin", "result.adminRegistry.everyoneIsAdmin", "result.profileDraft", "result.messageDraft", "result.hostMessageDraft", "result.roomDraft", "result.setProfileDraft", "result.setMessageDraft", "result.setHostMessageDraft", "result.setRoomDraft", "result.saveProfile", "result.sendTrustedMessage", "result.addTrustedRoom", "result.hostLookalikeSend", ], reason: "the everyone-is-admin flag's `true` branch carries the write claim its type declares" + "; and the drafts removed, with the trusted streams taking the text a " + "`cf-submit-input` click carries (docs/history/cfc-chat-demo-submit-input-break.md)", record: "docs/history/everyone-admin-write-claim-restored-break.md", }, { // The same break; against this older contract the proof blames the whole // registry rather than descending to the flag. pattern: "cfc-group-chat-demo/main.tsx", baselines: ["20260918T041802Z-YAJU948xc_bQwY0H"], paths: [ "argument.adminRegistry", "result.adminRegistry", "result.profileDraft", "result.messageDraft", "result.hostMessageDraft", "result.roomDraft", "result.setProfileDraft", "result.setMessageDraft", "result.setHostMessageDraft", "result.setRoomDraft", "result.saveProfile", "result.sendTrustedMessage", "result.addTrustedRoom", "result.hostLookalikeSend", ], reason: "the everyone-is-admin flag's `true` branch carries the write claim its type declares" + "; and the drafts removed, with the trusted streams taking the text a " + "`cf-submit-input` click carries (docs/history/cfc-chat-demo-submit-input-break.md)", record: "docs/history/everyone-admin-write-claim-restored-break.md", }, { // The CFC group chat demo's fields become `cf-submit-input`s, so Enter // gives the trusted gesture its writes require. The drafts and their // setter streams are removed, and the trusted streams take the submitted // text as their event. The older baselines carry this break in the // entries above that already name them. pattern: "cfc-group-chat-demo/main.tsx", baselines: ["20260923T205929Z-mHuHgI9LlBLCu53t"], paths: [ "result.profileDraft", "result.messageDraft", "result.hostMessageDraft", "result.roomDraft", "result.setProfileDraft", "result.setMessageDraft", "result.setHostMessageDraft", "result.setRoomDraft", "result.saveProfile", "result.sendTrustedMessage", "result.addTrustedRoom", "result.hostLookalikeSend", ], reason: "the drafts removed, with the trusted streams taking the text a `cf-submit-input` click carries", record: "docs/history/cfc-chat-demo-submit-input-break.md", }, { // Each `Panel` kind gains an optional `addedBy` DID. The proof does not // apply the open-object evolution allowance inside a union branch, so a // stored panel whose `addedBy` held a non-string reads as a refused // alternative. pattern: "loom/main.tsx", baselines: [ "20260920T232507Z-_ewvPy8qDJYL47km", "20260922T052256Z--2Q9ESzxSenSTer9", ], paths: [ "argument.panels[]", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "argument.presentation.focusedPanel", "argument.presentation.stagedPanels[]", ], reason: "a Loom panel's new optional addedBy reads as a narrowed union branch under baselines that never had the property" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/loom-panel-added-by-break.md", }, { // Each `Panel` kind's `addedBy` gains the `admitPanel` write contract and // the runtime's `authored-by` label as its type, which the proof reads as // a narrowed union branch, and the narrowed `Panel` reaches the `before` // of `addPanel`'s event. Under this baseline the pair already failed on // `argument.panels[]` for `addedByProfile`, which this entry also covers. pattern: "loom/main.tsx", baselines: ["20260923T232217Z-9unt7nppL26FihSK"], paths: [ "argument.panels[]", "result.addPanel.before", "result.addPanel.panel", "result.addPiece.addedBy", "result.duplicatePanel.addedBy", "result.duplicatePanel.before", "result.duplicatePanel.panel", "result.movePanel.before", "result.movePanel.panel", "result.panels[]", "result.removePanel.panel", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "argument.presentation.focusedPanel", "argument.presentation.stagedPanels[]", "result.presentation.focusedPanel", "result.presentation.stagedPanels[]", "result.setPresentation.focusedPanel", "result.setPresentation.stagedPanels[]", "result.viewerState.selectedPanel", ], reason: "a Loom panel's addedBy becomes the runtime-attested adder, written only by admitPanel, which reads as a narrowed union branch in the panels and in addPanel's event" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/loom-panel-attested-adder-break.md", }, { // The same change over the baseline that carries `addedByProfile`. An // admission event no longer names an adder, so `addedBy` leaves the // event of the three streams that add a panel. pattern: "loom/main.tsx", baselines: ["20260924T085224Z-oEtBQ4AVdy1fMTAB"], paths: [ "argument.panels[]", "result.addPanel.addedBy", "result.addPanel.before", "result.addPanel.panel", "result.addPiece.addedBy", "result.addPiece.before", "result.addPiece.panel", "result.duplicatePanel.addedBy", "result.duplicatePanel.before", "result.duplicatePanel.panel", "result.movePanel.before", "result.movePanel.panel", "result.panels[]", "result.removePanel.panel", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "argument.presentation.focusedPanel", "argument.presentation.stagedPanels[]", "result.presentation.focusedPanel", "result.presentation.stagedPanels[]", "result.setPresentation.focusedPanel", "result.setPresentation.stagedPanels[]", "result.viewerState.selectedPanel", ], reason: "a Loom panel's addedBy becomes the runtime-attested adder, written only by admitPanel, and an admission event no longer names one" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/loom-panel-attested-adder-break.md", }, { // The demo's release rule now pins two levels, `commit` and the `submit` // step beneath it, so the policy its briefs declare has a new digest, // which the proof reads as a changed label on the briefs. pattern: "cfc-exchange-rules/witnessed-chain.tsx", baselines: ["20260926T005010Z-wTSqH_JN5Vg6LFNp"], paths: [ "argument.briefs[]", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "argument.committed", ], reason: "the witnessed-chain demo's release rule pins the submit step beneath commit, which changes the declared policy's digest" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/witnessed-chain-two-level-break.md", }, { // Home's result slot `defaultProfile` gains the labels its type declares. // `TrustedDefaultProfile` is a labeled profile link beside `undefined`, // and the schema generator read that union as plain cells and dropped // the labels, so no baseline records them. They mark the slot, not the // cell the picker writes, so they gate no write (see the record). The // five home baselines the inbox entry above names report the same path // and stay with that entry, keeping the pairs disjoint. Home is a // required pattern, so this entry carries the ruling that lets it name // one. pattern: "system/home.tsx", baselines: [ "20260729T022742Z-mKLGw1aighDtz0A6", "20260818T220011Z-KnU5UM1qdaNt22eV", "20260918T215200Z-jpAh5dGwUi9mXmVz", "20260921T032753Z-6P1lIbz2DyCslReM", "20260921T034351Z-L6-4n7t2hSp4c9zK", "20260921T034425Z-2SJDIuEY_Tfn22zn", "20260921T060231Z-PWGPKZCDuyWqwSwC", "20260922T054240Z-GWbX89962ESG30mt", "20260922T062506Z-8jwCsMRoRpYix3Gp", "20260922T072811Z-lDfT9uaOpdQ85euK", "20260922T075652Z-hQWEhKVxnruVe95d", "20260922T162055Z-4Cvb8ipDmkleafD2", "20260923T173753Z-q-4fKdxnO8AE7OfY", "20260923T183517Z-q_fFTIwOH7X_PxWF", "20260923T205258Z-STa6M0JZsfFIPAkx", "20260923T225026Z-KWX9GtxW9KjSuIl9", "20260929T175237Z-sY6ZuenYIhmCyPPh", "20260930T050901Z-KQuFsaQLJAntgi-G", ], paths: ["result.defaultProfile"], reason: "home's result slot defaultProfile gains the writeAuthorizedBy, uiContract and addIntegrity its type declares, which the schema generator had dropped from a labeled cell beside undefined; they mark the slot rather than the cell the picker writes, which still writes it", record: "docs/history/home-default-profile-labels-break.md", requiredPatternOverride: { rulingBy: "Gideon", on: "2026-10-01", reason: "yeah i think we should do 1 now and follow up with 2. please proceed as you suggest, including with the one upgrade test", }, }, { // A THIRD entry for home, naming only the baselines recorded under or // after the entry above; the other 23 report the same path and stay with // the two entries that name them, keeping the pairs disjoint. // // Home's default profile moves from a link stored at the root of its own // cell to a link under `profile` in a slot cell (`DefaultProfileSlot`), // because a handle to a cell whose root holds a link denotes the linked // cell and so the picker could not re-point it. The slot is a fresh cell; // the cell the default was kept in stays, as `legacyDefaultProfile`, and // is the default until one is chosen in the slot. pattern: "system/home.tsx", baselines: [ "20261001T190916Z-5k9_Adl37zMhsNgG", "20261001T210138Z-P3RELdPaFKfIXROk", "20261003T000427Z-oEfsHL584h6qI8sa", ], paths: ["result.defaultProfile"], reason: "home's default profile moves under `profile` in a fresh slot cell so the picker can re-point it, and a default chosen before stays the default until one is chosen in the slot", record: "docs/history/home-default-profile-slot-break.md", requiredPatternOverride: { rulingBy: "Gideon", on: "2026-10-01", reason: 'preserve existing defaults: "i feel like we need to somehow preserve the default profile across this migration", then of the design that keeps the previous cell as the default until the slot holds one, "that sounds good to me. let\'s proceed as you suggest for 8373"', }, }, { // A THIRD entry for the picker, naming only baselines the two entries // above leave out. The picker's `defaultProfile` argument is home's slot, // which holds the default's link under `profile`, rather than the link. pattern: "system/profile-picker.tsx", baselines: [ "20260918T215200Z-jd2IozSP5n9l8UnE", "20260922T062506Z-a2dPgr0XCKC82UO6", "20260922T072811Z-s4HWEqeDMVTSnsl-", "20260922T075652Z-qC_3l84MczfDgjvh", "20260923T173753Z-1_LxUmwIZJz7WCut", "20260923T205258Z-B19D5XwDS0LdQdeY", "20261003T000427Z-YEfgzmp3UjJCJFgP", ], paths: ["argument.defaultProfile"], reason: "the picker's defaultProfile argument is home's slot holding the default's link under `profile`, rather than the link", record: "docs/history/home-default-profile-slot-break.md", }, { // A manager's room link gained `messages.count` and `messages.newestAt`. // The recorded link left every field but `about` open, so a stored // request outcome's room link admitted any `messages`; the candidate // types it. A link is always to a room output, whose `messages.count` is // a number, so no stored outcome reads differently. // // These baselines also report the scope the manager's `rooms` now // declares, which `fabrichat-view-scopes-break.md` records, so the // entry names that path beside its own. pattern: "fabrichat/manager.tsx", baselines: ["20261002T164437Z-O47ebJ7gn-iAk7TA"], paths: [ "argument.requests.*", "result.$VIEWS.chats.rooms", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.rooms", ], reason: "a manager's room link now types the room's `messages`, which the recorded link left open; every stored room link is to a room output whose `messages` the new type admits" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-room-link-messages-break.md", }, { // A manager's index entry gained `revision`, the revision of the room's // entry in the user's catalog, which a request to forget the room names, // so that a choice made since by another client is not overridden, and a // refused outcome gained `code`, which a client acts on. The recorded // outcomes left extra fields open, so a stored outcome admitted either of // any type; the candidate types them. No recorded outcome holds either. // // These baselines also report the scope the manager's `rooms` now // declares, which `fabrichat-view-scopes-break.md` records, so the // entry names that path beside its own. pattern: "fabrichat/manager.tsx", baselines: [ "20261005T182129Z-yX4jdpH1wLhIowBh", "20261006T233809Z-8LxrZWka1s7az21n", "20261008T155754Z-m9jfHg3UGeF0e9_8", "20261008T210909Z-Kyy64jL0hYC-5p6Q", ], paths: [ "argument.requests.*", "result.$VIEWS.chats.rooms", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.rooms", ], reason: "a manager's index entry now types `revision`, and a refused outcome `code`, which the recorded outcomes left open; no stored request outcome holds either" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-index-revision-break.md", }, { // A manager's room link gained `roster`, the profiles of those who joined // the room, each a link, from which the manager derives its `people`. The // recorded link left it open, so a stored outcome admitted any `roster`; // the candidate types it. A link is always to a room output, which has no // `roster` or has a list of profile links. // // These baselines also report the scope the manager's `rooms` now // declares, which `fabrichat-view-scopes-break.md` records, so the // entry names that path beside its own. They also report the `delivery` // a request outcome gained, under the manager's views, and the entry // names that path too, which `fabrichat-add-member-offer-break.md` // records. pattern: "fabrichat/manager.tsx", baselines: [ "20261008T225324Z-Oj3DbCTq-94tEYN3", "20261009T161813Z-r7DggcJdZ7FzrPCR", "20261009T210116Z-99YN5H9jf2UFET6M", "20261010T083035Z-Mp5ZALK-A2rUfm_u", ], paths: [ "argument.requests.*", "result.$VIEWS.chats.rooms", "result.$VIEWS.chats.requests.*", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.requests.*", "result.rooms", ], reason: "a manager's room link now types the room's `roster`, which the recorded link left open; every stored room link is to a room output with no `roster` or with a list of profile links, which the new type admits" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-room-link-roster-break.md", }, { // The manager's `rooms` and `people` declare the per-session scope the // computeds deriving them already had. This is the one baseline that has // `people`; the baselines the entries above name report `rooms` beside // their own paths. // // This baseline also reports the `delivery` and the refusal `code` a // stored request outcome gained, which // `fabrichat-add-member-offer-break.md` records, so the entry names that // path beside its own. pattern: "fabrichat/manager.tsx", baselines: [ "20261011T013628Z-pqvm47igo4Famzxe", ], paths: [ "result.$VIEWS.chats.rooms", "result.$VIEWS.chats.people", "argument.requests.*", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.$VIEWS.chats.requests.*", "result.people", "result.requests.*", "result.rooms", ], reason: "a manager's rooms and people declare the per-session scope they are derived in; nothing is stored at either path for a reader to refuse" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-view-scopes-break.md", }, { // A room's policy gained an optional `maxAttachments`. The policy's // schema allows other keys, so typing this one narrows it, and a // manager's request outcomes carry the policy through the rooms they // link. // // These baselines also report the scope the manager's `people` declares, // which `fabrichat-view-scopes-per-user-break.md` records, in the result // role. The entry names both paths, and the last baseline, recorded with // that scope, reports the policy alone. pattern: "fabrichat/manager.tsx", baselines: [ "20261011T221322Z-ESDR30hfSt52JJjG", "20261012T173536Z-6WvdcsJ1uCY7_PMp", "20261013T211911Z-_KGvbNdJDAorzeH2", "20261014T030847Z--3DmbOSzIygprqSe", "20261014T162031Z-5e6WmbJILlZPfDKs", "20261015T201316Z-Sd2QSmU_za1kG0sR", "20261015T211658Z-urNzNYcruTANHQRY", "20261016T130411Z-0Lt2aLoYFhOy5W4t", "20261016T131516Z-zwm-rd7FOQzgJmf2", "20261016T150221Z-BMe3uZoF-rfz0nHI", "20261016T232233Z-pyVPXvcNYTbzFVqa", "20261018T181023Z-H3M1K82AIA1y33AS", "20261022T220213Z-LlstD45te1meAfuA", "20261024T002137Z-_xficjXREAbKWap9", ], paths: [ "argument.requests.*", "result.$VIEWS.chats.people", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.$VIEWS.chats.rooms", "result.people", "result.rooms", ], reason: "a room's policy states `maxAttachments`, an optional number, where its schema took any value; no stored policy holds the key" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-max-attachments-break.md", }, { // Home types its `chatManager` as the manager's output, so the scope the // manager's `rooms` declares reaches home's contract too. Home is a // required pattern, so this entry carries the ruling that lets it name // one. pattern: "system/home.tsx", baselines: [ "20261003T212417Z-SrR1RyP2_xSZaWGa", "20261003T224735Z-H6PR-p3yRuZx4uT2", "20261005T182130Z-wlXO2zgoo42UKOky", "20261005T223520Z-cZ5NgFU22GEGoqDI", "20261005T225548Z-wpkYIzoula4xOPoD", "20261006T012716Z-qzkTtxDyl_hBI5Zd", "20261006T175424Z-q70r8YAKNKfMN02V", "20261006T233810Z-JdwmtehG5ssBW1m_", "20261007T161831Z-ir1SbxT9QugCd0Sh", "20261007T225245Z-rfcz49a1bwITmz8H", "20261008T022419Z-oJyRo7Wribob4Zfx", "20261008T155754Z-k1iDJCnYbFdKtyBz", "20261008T164451Z-n7gF99zc-4syFWet", "20261008T210117Z-UFEwl2NpHQpxqXsF", "20261008T214130Z-p3Zx6MHfQub4Jhqr", "20261008T231303Z-40_BirmSRf8AZ9Su", ], paths: [ "result.chatManager.$VIEWS.chats.rooms", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.chatManager.rooms", ], reason: "home's chat manager's rooms declare the per-session scope they are derived in; a home rolled forward still delivers them, and nothing is stored at that path for a reader to refuse" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-view-scopes-break.md", requiredPatternOverride: { rulingBy: "Dan", on: "2026-10-10", reason: 'choosing to declare the scope once the measurements were in: "it looks like (b) is more correct to me", then "(a) sounds good"', }, }, { // The same ruling, against the one home baseline whose manager has // `people`, which declares its scope beside `rooms`. pattern: "system/home.tsx", baselines: [ "20261011T013629Z-onNetb9BZoDKytX7", ], paths: [ "result.chatManager.$VIEWS.chats.rooms", "result.chatManager.$VIEWS.chats.people", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.chatManager.$VIEWS.chats.requests.*", "result.chatManager.people", "result.chatManager.requests.*", "result.chatManager.rooms", ], reason: "home's chat manager's rooms and people declare the per-session scope they are derived in; a home rolled forward still delivers them, and nothing is stored at either path for a reader to refuse" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-view-scopes-break.md", requiredPatternOverride: { rulingBy: "Dan", on: "2026-10-10", reason: 'choosing to declare the scope once the measurements were in: "it looks like (b) is more correct to me", then "(a) sounds good"', }, }, { // Two baselines of the default-profile slot break, whose proof blames // the scope the manager's `rooms` declares under home's `chatManager` // beside `result.defaultProfile`. The entry names both paths. `home-default-profile-slot-break.md` // records the first, with the ruling its own entry carries, and this // record the second. pattern: "system/home.tsx", baselines: [ "20261002T164437Z-Ppiw9bONPOzUfI_d", "20261003T003223Z-fDj2SHhwNCXbd-O3", ], paths: [ "result.defaultProfile", "result.chatManager.$VIEWS.chats.rooms", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.chatManager.rooms", ], reason: "home's chat manager's rooms declare the per-session scope they are derived in, and its default profile moved under a slot cell as the slot break records; a home rolled forward still delivers both" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-view-scopes-break.md", requiredPatternOverride: { rulingBy: "Dan", on: "2026-10-10", reason: 'choosing to declare the scope once the measurements were in: "it looks like (b) is more correct to me", then "(a) sounds good"', }, }, { // A request outcome gained `delivery`, which says how `offerRoom` told a // member added to a room of it, and a refused one the `shared-inbox` // code. The recorded outcomes left extra fields open and typed `code` as // `space-own-chat` alone, so a stored outcome admitted either of any // type; the candidate types them. // // The proof also blames the scope the manager's `people` declares, which // `fabrichat-view-scopes-per-user-break.md` records. The entry names both // paths. pattern: "fabrichat/manager.tsx", baselines: [ "20261011T170652Z-2XdZAneyCTt2Teex", ], paths: [ "argument.requests.*", "result.$VIEWS.chats.requests.*", "result.$VIEWS.chats.people", "result.requests.*", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.$VIEWS.chats.rooms", "result.people", "result.rooms", ], reason: "a manager's request outcome now types `delivery`, and a refused one the `shared-inbox` code, which the recorded outcomes left open; no stored request outcome holds either" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-add-member-offer-break.md", }, { // Home types its `chatManager` as the manager's output, so the `delivery` // and the refusal code a manager's request outcome gained reach home's // contract too. These baselines also report the scope the manager's // `rooms` declares, which `fabrichat-view-scopes-break.md` records under // the same ruling it carries there, and the proof blames `requests` // beside it. The entry names both paths. Home is a required pattern, so it carries the ruling that lets // it name one. pattern: "system/home.tsx", baselines: [ "20261008T225325Z-PhnyFM45uYaav17c", "20261009T161814Z-Oyyi7wIUz7AJ5r33", "20261009T210117Z-3GKaIZwG8Yel9N7f", "20261010T055011Z-kPOS_bsln0EOlG9e", ], paths: [ "result.chatManager.$VIEWS.chats.rooms", "result.chatManager.$VIEWS.chats.requests.*", "result.chatManager.requests.*", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.chatManager.rooms", ], reason: "home's chat manager's request outcomes now type `delivery`, and a refused one the `shared-inbox` code, and its rooms declare the per-session scope they are derived in; a home rolled forward still delivers both" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-add-member-offer-break.md", requiredPatternOverride: { rulingBy: "Dan", on: "2026-10-11", reason: "taking home's part of the break once its roll-forward was measured: \"assuming the contract breakage can be automatically handled the way the previous one was, then that's okay\"", }, }, { // The same ruling, against the home baselines recorded with the scope // the manager's views declare, and with the action that replaces a // refused private inbox. The proof also blames the scope the manager's // `people` declares, which `fabrichat-view-scopes-per-user-break.md` // records under the ruling its own entry carries. The entry names both // paths. pattern: "system/home.tsx", baselines: [ "20261011T170655Z-AJPqLNiOact-MHN0", "20261011T215215Z-wYgeQ3_Ossuzky4g", ], paths: [ "result.chatManager.$VIEWS.chats.requests.*", "result.chatManager.$VIEWS.chats.people", "result.chatManager.requests.*", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.chatManager.$VIEWS.chats.rooms", "result.chatManager.people", "result.chatManager.rooms", ], reason: "home's chat manager's request outcomes now type `delivery`, and a refused one the `shared-inbox` code, which the recorded outcomes left open; a home rolled forward still delivers them" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-add-member-offer-break.md", requiredPatternOverride: { rulingBy: "Dan", on: "2026-10-11", reason: "taking home's part of the break once its roll-forward was measured: \"assuming the contract breakage can be automatically handled the way the previous one was, then that's okay\"", }, }, { // A room's messages became objects pushed onto the list, each labeled // with its writer under a policy naming the room's four send handlers, // its edit, delete, and obliterate handlers; the stored shape, keyed // records under a policy naming the old handlers, is left behind. Every // recorded room baseline reads that as a changed `ifc` on the messages' // elements, and each also reports the results the room no longer offers: // its activity log, its per-user record of act outcomes, or its message // windows, as each baseline offered them. // // These four, the oldest, report `argument.about` as well, the start // reviewed break `fabrichat-start-reviewed-break.md` records; the entry // that forgave it alone could forgive nothing once the messages broke // beside it, so this entry names both. pattern: "fabrichat/room.tsx", baselines: [ "20261002T164437Z-1xU0r9QuhxWHgK6y", "20261003T224731Z-o9skqwp4KfLbCDBT", "20261005T182129Z-3RSVlUS0NdLuz2VP", "20261005T224806Z-OeD1Mc2I_LQ_d8L_", ], paths: [ "argument.about", "result.recentActivity", "argument.messages[]", "result.$VIEWS.room.recentActivity", "result.$VIEWS.room.deleteMessage.message.reactions[]", "result.$VIEWS.room.deleteMessage.message.replyTo.message.reactions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteMessage.replyTo.message.reactions", "result.$VIEWS.room.deleteMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteReaction.message.reactions[]", "result.$VIEWS.room.deleteReaction.message.replyTo.message.reactions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteReaction.replyTo.message.reactions", "result.$VIEWS.room.deleteReaction.replyTo.message.replyTo.message", "result.$VIEWS.room.editMessage.message.reactions[]", "result.$VIEWS.room.editMessage.message.replyTo.message.reactions", "result.$VIEWS.room.editMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.editMessage.replyTo.message.reactions", "result.$VIEWS.room.editMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.messages.closeWindow", "result.$VIEWS.room.messages.windows", "result.$VIEWS.room.messages.latest.messages[].reactions[]", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.reactions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.replyTo.message", "result.$VIEWS.room.obliterateMessage.message.reactions[]", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.reactions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.obliterateMessage.replyTo.message.reactions", "result.$VIEWS.room.obliterateMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.sendMessage.message.reactions[]", "result.$VIEWS.room.sendMessage.message.replyTo.message.reactions", "result.$VIEWS.room.sendMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.sendMessage.replyTo.message.reactions", "result.$VIEWS.room.sendMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.sendReaction.message.reactions[]", "result.$VIEWS.room.sendReaction.message.replyTo.message.reactions", "result.$VIEWS.room.sendReaction.message.replyTo.message.replyTo.message", "result.$VIEWS.room.sendReaction.replyTo.message.reactions", "result.$VIEWS.room.sendReaction.replyTo.message.replyTo.message", "result.deleteMessage.message.reactions[]", "result.deleteMessage.message.replyTo.message.reactions", "result.deleteMessage.message.replyTo.message.replyTo.message", "result.deleteMessage.replyTo.message.reactions", "result.deleteMessage.replyTo.message.replyTo.message", "result.deleteReaction.message.reactions[]", "result.deleteReaction.message.replyTo.message.reactions", "result.deleteReaction.message.replyTo.message.replyTo.message", "result.deleteReaction.replyTo.message.reactions", "result.deleteReaction.replyTo.message.replyTo.message", "result.editMessage.message.reactions[]", "result.editMessage.message.replyTo.message.reactions", "result.editMessage.message.replyTo.message.replyTo.message", "result.editMessage.replyTo.message.reactions", "result.editMessage.replyTo.message.replyTo.message", "result.messages.closeWindow", "result.messages.windows", "result.messages.latest.messages[].reactions[]", "result.messages.latest.messages[].replyTo.message.reactions", "result.messages.latest.messages[].replyTo.message.replyTo.message", "result.obliterateMessage.message.reactions[]", "result.obliterateMessage.message.replyTo.message.reactions", "result.obliterateMessage.message.replyTo.message.replyTo.message", "result.obliterateMessage.replyTo.message.reactions", "result.obliterateMessage.replyTo.message.replyTo.message", "result.sendMessage.message.reactions[]", "result.sendMessage.message.replyTo.message.reactions", "result.sendMessage.message.replyTo.message.replyTo.message", "result.sendMessage.replyTo.message.reactions", "result.sendMessage.replyTo.message.replyTo.message", "result.sendReaction.message.reactions[]", "result.sendReaction.message.replyTo.message.reactions", "result.sendReaction.message.replyTo.message.replyTo.message", "result.sendReaction.replyTo.message.reactions", "result.sendReaction.replyTo.message.replyTo.message", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.recentActivityExpiredThrough", "result.$VIEWS.room.recentActivityExpiredThrough", "result.$VIEWS.room.deleteMessage.requestId", "result.$VIEWS.room.deleteMessage.version", "result.$VIEWS.room.deleteMessage.message.earlierVersions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.deleteMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteMessage.replyTo.message.editedAt", "result.$VIEWS.room.deleteReaction.requestId", "result.$VIEWS.room.deleteReaction.version", "result.$VIEWS.room.deleteReaction.message.earlierVersions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.editedAt", "result.$VIEWS.room.deleteReaction.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteReaction.replyTo.message.editedAt", "result.$VIEWS.room.editMessage.requestId", "result.$VIEWS.room.editMessage.version", "result.$VIEWS.room.editMessage.message.earlierVersions", "result.$VIEWS.room.editMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.editMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.editMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.editMessage.replyTo.message.editedAt", "result.$VIEWS.room.messages.openWindow", "result.$VIEWS.room.messages.latest.messages[].earlierVersions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.earlierVersions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.editedAt", "result.$VIEWS.room.obliterateMessage.requestId", "result.$VIEWS.room.obliterateMessage.version", "result.$VIEWS.room.obliterateMessage.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.obliterateMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.replyTo.message.editedAt", "result.$VIEWS.room.sendMessage.requestId", "result.$VIEWS.room.sendMessage.version", "result.$VIEWS.room.sendMessage.message.earlierVersions", "result.$VIEWS.room.sendMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.sendMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.sendMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.sendMessage.replyTo.message.editedAt", "result.$VIEWS.room.sendReaction.requestId", "result.$VIEWS.room.sendReaction.version", "result.$VIEWS.room.sendReaction.message.earlierVersions", "result.$VIEWS.room.sendReaction.message.replyTo.message.earlierVersions", "result.$VIEWS.room.sendReaction.message.replyTo.message.editedAt", "result.$VIEWS.room.sendReaction.replyTo.message.earlierVersions", "result.$VIEWS.room.sendReaction.replyTo.message.editedAt", "result.deleteMessage.requestId", "result.deleteMessage.version", "result.deleteMessage.message.earlierVersions", "result.deleteMessage.message.replyTo.message.earlierVersions", "result.deleteMessage.message.replyTo.message.editedAt", "result.deleteMessage.replyTo.message.earlierVersions", "result.deleteMessage.replyTo.message.editedAt", "result.deleteReaction.requestId", "result.deleteReaction.version", "result.deleteReaction.message.earlierVersions", "result.deleteReaction.message.replyTo.message.earlierVersions", "result.deleteReaction.message.replyTo.message.editedAt", "result.deleteReaction.replyTo.message.earlierVersions", "result.deleteReaction.replyTo.message.editedAt", "result.editMessage.requestId", "result.editMessage.version", "result.editMessage.message.earlierVersions", "result.editMessage.message.replyTo.message.earlierVersions", "result.editMessage.message.replyTo.message.editedAt", "result.editMessage.replyTo.message.earlierVersions", "result.editMessage.replyTo.message.editedAt", "result.messages.openWindow", "result.messages.latest.messages[].earlierVersions", "result.messages.latest.messages[].replyTo.message.earlierVersions", "result.messages.latest.messages[].replyTo.message.editedAt", "result.obliterateMessage.requestId", "result.obliterateMessage.version", "result.obliterateMessage.message.earlierVersions", "result.obliterateMessage.message.replyTo.message.earlierVersions", "result.obliterateMessage.message.replyTo.message.editedAt", "result.obliterateMessage.replyTo.message.earlierVersions", "result.obliterateMessage.replyTo.message.editedAt", "result.sendMessage.requestId", "result.sendMessage.version", "result.sendMessage.message.earlierVersions", "result.sendMessage.message.replyTo.message.earlierVersions", "result.sendMessage.message.replyTo.message.editedAt", "result.sendMessage.replyTo.message.earlierVersions", "result.sendMessage.replyTo.message.editedAt", "result.sendReaction.requestId", "result.sendReaction.version", "result.sendReaction.message.earlierVersions", "result.sendReaction.message.replyTo.message.earlierVersions", "result.sendReaction.message.replyTo.message.editedAt", "result.sendReaction.replyTo.message.earlierVersions", "result.sendReaction.replyTo.message.editedAt", ], reason: "a room's messages are objects pushed onto the list under a policy naming the new handlers, and its activity log is gone; rooms holding the keyed records are left behind" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-pushed-messages-break.md", }, { // The same break, against the baselines that offered the activity log. pattern: "fabrichat/room.tsx", baselines: [ "20261006T233809Z-D8hKhP8UI9lV8o-V", "20261006T235529Z-O5mJyExuecHZTzFi", "20261007T155000Z-IuMW8BStP8yd3YI4", "20261008T151801Z-2znk1fYLY0WPYJEd", "20261008T164416Z-F91XV4kdnGBtzoC7", "20261008T170824Z-jJ7xN7PhS-C9R7kR", "20261008T220159Z-qhC4uKph2n7h9FAc", "20261008T231303Z-tDxf_330zvg25E0f", "20261009T151612Z-bGNnPCNd9MdwuN-E", "20261009T161814Z-XcQsGUlUHykDvj3q", "20261009T175600Z-hCz9KamK27xnIKtH", "20261009T190753Z-ttsXGWoz9jzpIGm4", "20261009T204342Z-CDs_MQ1XE2LCiH4u", "20261009T224608Z-kbmYR940TBNMF_bI", "20261009T232213Z--scSLE7mEm1_Fn1A", "20261010T060935Z-zf5A0zVmTHpJWJf1", "20261010T142754Z-6o6cHELOFbTiS6Hv", "20261011T013628Z-OxhmgRqIGmFAsRKK", "20261011T170654Z-UFD8OhjCLdeg6beK", "20261011T215217Z-4O-p88WPN-QPVIFc", "20261011T232405Z-u3fFO-4p-4g9Uwmb", "20261012T012643Z-5qipj6ZBTegHULGC", "20261012T173536Z-tFpgfWWy0En57xYi", "20261012T175406Z-rQlPQaz2bt4YpckB", "20261013T054345Z-TZbbPuHVZjx_WmV-", "20261013T065554Z-t9eat6Sqm-vvdn2q", "20261013T165014Z-HwNYLPqtGCoOwfhi", "20261013T165725Z-20j_rjoiPR2WTBVX", "20261013T175245Z-qSzSqmttfWLSJotw", "20261013T181948Z-ESqKYLsNLOgxeFAL", "20261013T223149Z-1UouAjk3LgOrndVt", ], paths: [ "argument.messages[]", "result.recentActivity", "result.$VIEWS.room.recentActivity", "result.$VIEWS.room.deleteMessage.message.reactions[]", "result.$VIEWS.room.deleteMessage.message.replyTo.message.reactions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteMessage.replyTo.message.reactions", "result.$VIEWS.room.deleteMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteReaction.message.reactions[]", "result.$VIEWS.room.deleteReaction.message.replyTo.message.reactions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteReaction.replyTo.message.reactions", "result.$VIEWS.room.deleteReaction.replyTo.message.replyTo.message", "result.$VIEWS.room.editMessage.message.reactions[]", "result.$VIEWS.room.editMessage.message.replyTo.message.reactions", "result.$VIEWS.room.editMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.editMessage.replyTo.message.reactions", "result.$VIEWS.room.editMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.messages.closeWindow", "result.$VIEWS.room.messages.windows", "result.$VIEWS.room.messages.latest.messages[].reactions[]", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.reactions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.replyTo.message", "result.$VIEWS.room.obliterateMessage.message.reactions[]", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.reactions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.obliterateMessage.replyTo.message.reactions", "result.$VIEWS.room.obliterateMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.sendMessage.message.reactions[]", "result.$VIEWS.room.sendMessage.message.replyTo.message.reactions", "result.$VIEWS.room.sendMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.sendMessage.replyTo.message.reactions", "result.$VIEWS.room.sendMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.sendReaction.message.reactions[]", "result.$VIEWS.room.sendReaction.message.replyTo.message.reactions", "result.$VIEWS.room.sendReaction.message.replyTo.message.replyTo.message", "result.$VIEWS.room.sendReaction.replyTo.message.reactions", "result.$VIEWS.room.sendReaction.replyTo.message.replyTo.message", "result.deleteMessage.message.reactions[]", "result.deleteMessage.message.replyTo.message.reactions", "result.deleteMessage.message.replyTo.message.replyTo.message", "result.deleteMessage.replyTo.message.reactions", "result.deleteMessage.replyTo.message.replyTo.message", "result.deleteReaction.message.reactions[]", "result.deleteReaction.message.replyTo.message.reactions", "result.deleteReaction.message.replyTo.message.replyTo.message", "result.deleteReaction.replyTo.message.reactions", "result.deleteReaction.replyTo.message.replyTo.message", "result.editMessage.message.reactions[]", "result.editMessage.message.replyTo.message.reactions", "result.editMessage.message.replyTo.message.replyTo.message", "result.editMessage.replyTo.message.reactions", "result.editMessage.replyTo.message.replyTo.message", "result.messages.closeWindow", "result.messages.windows", "result.messages.latest.messages[].reactions[]", "result.messages.latest.messages[].replyTo.message.reactions", "result.messages.latest.messages[].replyTo.message.replyTo.message", "result.obliterateMessage.message.reactions[]", "result.obliterateMessage.message.replyTo.message.reactions", "result.obliterateMessage.message.replyTo.message.replyTo.message", "result.obliterateMessage.replyTo.message.reactions", "result.obliterateMessage.replyTo.message.replyTo.message", "result.sendMessage.message.reactions[]", "result.sendMessage.message.replyTo.message.reactions", "result.sendMessage.message.replyTo.message.replyTo.message", "result.sendMessage.replyTo.message.reactions", "result.sendMessage.replyTo.message.replyTo.message", "result.sendReaction.message.reactions[]", "result.sendReaction.message.replyTo.message.reactions", "result.sendReaction.message.replyTo.message.replyTo.message", "result.sendReaction.replyTo.message.reactions", "result.sendReaction.replyTo.message.replyTo.message", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.recentActivityExpiredThrough", "result.$VIEWS.room.recentActivityExpiredThrough", "result.$VIEWS.room.deleteMessage.requestId", "result.$VIEWS.room.deleteMessage.version", "result.$VIEWS.room.deleteMessage.message.earlierVersions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.deleteMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteMessage.replyTo.message.editedAt", "result.$VIEWS.room.deleteReaction.requestId", "result.$VIEWS.room.deleteReaction.version", "result.$VIEWS.room.deleteReaction.message.earlierVersions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.editedAt", "result.$VIEWS.room.deleteReaction.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteReaction.replyTo.message.editedAt", "result.$VIEWS.room.editMessage.requestId", "result.$VIEWS.room.editMessage.version", "result.$VIEWS.room.editMessage.message.earlierVersions", "result.$VIEWS.room.editMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.editMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.editMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.editMessage.replyTo.message.editedAt", "result.$VIEWS.room.messages.openWindow", "result.$VIEWS.room.messages.latest.messages[].earlierVersions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.earlierVersions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.editedAt", "result.$VIEWS.room.obliterateMessage.requestId", "result.$VIEWS.room.obliterateMessage.version", "result.$VIEWS.room.obliterateMessage.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.obliterateMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.replyTo.message.editedAt", "result.$VIEWS.room.sendMessage.requestId", "result.$VIEWS.room.sendMessage.version", "result.$VIEWS.room.sendMessage.message.earlierVersions", "result.$VIEWS.room.sendMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.sendMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.sendMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.sendMessage.replyTo.message.editedAt", "result.$VIEWS.room.sendReaction.requestId", "result.$VIEWS.room.sendReaction.version", "result.$VIEWS.room.sendReaction.message.earlierVersions", "result.$VIEWS.room.sendReaction.message.replyTo.message.earlierVersions", "result.$VIEWS.room.sendReaction.message.replyTo.message.editedAt", "result.$VIEWS.room.sendReaction.replyTo.message.earlierVersions", "result.$VIEWS.room.sendReaction.replyTo.message.editedAt", "result.deleteMessage.requestId", "result.deleteMessage.version", "result.deleteMessage.message.earlierVersions", "result.deleteMessage.message.replyTo.message.earlierVersions", "result.deleteMessage.message.replyTo.message.editedAt", "result.deleteMessage.replyTo.message.earlierVersions", "result.deleteMessage.replyTo.message.editedAt", "result.deleteReaction.requestId", "result.deleteReaction.version", "result.deleteReaction.message.earlierVersions", "result.deleteReaction.message.replyTo.message.earlierVersions", "result.deleteReaction.message.replyTo.message.editedAt", "result.deleteReaction.replyTo.message.earlierVersions", "result.deleteReaction.replyTo.message.editedAt", "result.editMessage.requestId", "result.editMessage.version", "result.editMessage.message.earlierVersions", "result.editMessage.message.replyTo.message.earlierVersions", "result.editMessage.message.replyTo.message.editedAt", "result.editMessage.replyTo.message.earlierVersions", "result.editMessage.replyTo.message.editedAt", "result.messages.openWindow", "result.messages.latest.messages[].earlierVersions", "result.messages.latest.messages[].replyTo.message.earlierVersions", "result.messages.latest.messages[].replyTo.message.editedAt", "result.obliterateMessage.requestId", "result.obliterateMessage.version", "result.obliterateMessage.message.earlierVersions", "result.obliterateMessage.message.replyTo.message.earlierVersions", "result.obliterateMessage.message.replyTo.message.editedAt", "result.obliterateMessage.replyTo.message.earlierVersions", "result.obliterateMessage.replyTo.message.editedAt", "result.sendMessage.requestId", "result.sendMessage.version", "result.sendMessage.message.earlierVersions", "result.sendMessage.message.replyTo.message.earlierVersions", "result.sendMessage.message.replyTo.message.editedAt", "result.sendMessage.replyTo.message.earlierVersions", "result.sendMessage.replyTo.message.editedAt", "result.sendReaction.requestId", "result.sendReaction.version", "result.sendReaction.message.earlierVersions", "result.sendReaction.message.replyTo.message.earlierVersions", "result.sendReaction.message.replyTo.message.editedAt", "result.sendReaction.replyTo.message.earlierVersions", "result.sendReaction.replyTo.message.editedAt", "result.$VIEWS.room.participantPrincipals", "result.participantPrincipals", "result.$VIEWS.room.participantEntries", "result.participantEntries", ], reason: "a room's messages are objects pushed onto the list under a policy naming the new handlers, and its activity log is gone; rooms holding the keyed records are left behind" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-pushed-messages-break.md", }, { // The same break, against the baselines that offered the per-user act // outcomes. pattern: "fabrichat/room.tsx", baselines: [ "20261014T012736Z-lylYV6qdLO9BesnG", "20261014T025519Z-0k_a1bve4vofmYu-", "20261014T030847Z-kT_cHSAop5rMoIoq", "20261014T032931Z-HZkjsOAXJP_gQyA3", "20261014T123129Z-VlmPp0bPiXq8MNex", "20261014T130013Z-uRhft5bPPY03WmU6", "20261014T142812Z-p_fHr5eLl9Kdq7am", ], paths: [ "argument.messages[]", "result.messageRequests", "result.recentActivity", "result.$VIEWS.room.messageRequests", "result.$VIEWS.room.recentActivity", "result.$VIEWS.room.deleteMessage.message.reactions[]", "result.$VIEWS.room.deleteMessage.message.replyTo.message.reactions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteMessage.replyTo.message.reactions", "result.$VIEWS.room.deleteMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteReaction.message.reactions[]", "result.$VIEWS.room.deleteReaction.message.replyTo.message.reactions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteReaction.replyTo.message.reactions", "result.$VIEWS.room.deleteReaction.replyTo.message.replyTo.message", "result.$VIEWS.room.editMessage.message.reactions[]", "result.$VIEWS.room.editMessage.message.replyTo.message.reactions", "result.$VIEWS.room.editMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.editMessage.replyTo.message.reactions", "result.$VIEWS.room.editMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.messages.closeWindow", "result.$VIEWS.room.messages.windows", "result.$VIEWS.room.messages.latest.messages[].reactions[]", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.reactions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.replyTo.message", "result.$VIEWS.room.obliterateMessage.message.reactions[]", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.reactions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.obliterateMessage.replyTo.message.reactions", "result.$VIEWS.room.obliterateMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.sendMessage.message.reactions[]", "result.$VIEWS.room.sendMessage.message.replyTo.message.reactions", "result.$VIEWS.room.sendMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.sendMessage.replyTo.message.reactions", "result.$VIEWS.room.sendMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.sendReaction.message.reactions[]", "result.$VIEWS.room.sendReaction.message.replyTo.message.reactions", "result.$VIEWS.room.sendReaction.message.replyTo.message.replyTo.message", "result.$VIEWS.room.sendReaction.replyTo.message.reactions", "result.$VIEWS.room.sendReaction.replyTo.message.replyTo.message", "result.deleteMessage.message.reactions[]", "result.deleteMessage.message.replyTo.message.reactions", "result.deleteMessage.message.replyTo.message.replyTo.message", "result.deleteMessage.replyTo.message.reactions", "result.deleteMessage.replyTo.message.replyTo.message", "result.deleteReaction.message.reactions[]", "result.deleteReaction.message.replyTo.message.reactions", "result.deleteReaction.message.replyTo.message.replyTo.message", "result.deleteReaction.replyTo.message.reactions", "result.deleteReaction.replyTo.message.replyTo.message", "result.editMessage.message.reactions[]", "result.editMessage.message.replyTo.message.reactions", "result.editMessage.message.replyTo.message.replyTo.message", "result.editMessage.replyTo.message.reactions", "result.editMessage.replyTo.message.replyTo.message", "result.messages.closeWindow", "result.messages.windows", "result.messages.latest.messages[].reactions[]", "result.messages.latest.messages[].replyTo.message.reactions", "result.messages.latest.messages[].replyTo.message.replyTo.message", "result.obliterateMessage.message.reactions[]", "result.obliterateMessage.message.replyTo.message.reactions", "result.obliterateMessage.message.replyTo.message.replyTo.message", "result.obliterateMessage.replyTo.message.reactions", "result.obliterateMessage.replyTo.message.replyTo.message", "result.sendMessage.message.reactions[]", "result.sendMessage.message.replyTo.message.reactions", "result.sendMessage.message.replyTo.message.replyTo.message", "result.sendMessage.replyTo.message.reactions", "result.sendMessage.replyTo.message.replyTo.message", "result.sendReaction.message.reactions[]", "result.sendReaction.message.replyTo.message.reactions", "result.sendReaction.message.replyTo.message.replyTo.message", "result.sendReaction.replyTo.message.reactions", "result.sendReaction.replyTo.message.replyTo.message", "result.$VIEWS.room.messages.threads[].root.reactions[]", "result.$VIEWS.room.messages.threads[].root.replyTo.message.reactions", "result.$VIEWS.room.messages.threads[].root.replyTo.message.replyTo.message", "result.messages.threads[].root.reactions[]", "result.messages.threads[].root.replyTo.message.reactions", "result.messages.threads[].root.replyTo.message.replyTo.message", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.recentActivityExpiredThrough", "result.$VIEWS.room.recentActivityExpiredThrough", "result.$VIEWS.room.deleteMessage.requestId", "result.$VIEWS.room.deleteMessage.version", "result.$VIEWS.room.deleteMessage.message.earlierVersions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.deleteMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteMessage.replyTo.message.editedAt", "result.$VIEWS.room.deleteReaction.requestId", "result.$VIEWS.room.deleteReaction.version", "result.$VIEWS.room.deleteReaction.message.earlierVersions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.editedAt", "result.$VIEWS.room.deleteReaction.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteReaction.replyTo.message.editedAt", "result.$VIEWS.room.editMessage.requestId", "result.$VIEWS.room.editMessage.version", "result.$VIEWS.room.editMessage.message.earlierVersions", "result.$VIEWS.room.editMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.editMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.editMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.editMessage.replyTo.message.editedAt", "result.$VIEWS.room.messages.openWindow", "result.$VIEWS.room.messages.latest.messages[].earlierVersions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.earlierVersions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.editedAt", "result.$VIEWS.room.obliterateMessage.requestId", "result.$VIEWS.room.obliterateMessage.version", "result.$VIEWS.room.obliterateMessage.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.obliterateMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.replyTo.message.editedAt", "result.$VIEWS.room.participantEntries", "result.$VIEWS.room.participantPrincipals", "result.$VIEWS.room.sendMessage.requestId", "result.$VIEWS.room.sendMessage.version", "result.$VIEWS.room.sendMessage.message.earlierVersions", "result.$VIEWS.room.sendMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.sendMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.sendMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.sendMessage.replyTo.message.editedAt", "result.$VIEWS.room.sendReaction.requestId", "result.$VIEWS.room.sendReaction.version", "result.$VIEWS.room.sendReaction.message.earlierVersions", "result.$VIEWS.room.sendReaction.message.replyTo.message.earlierVersions", "result.$VIEWS.room.sendReaction.message.replyTo.message.editedAt", "result.$VIEWS.room.sendReaction.replyTo.message.earlierVersions", "result.$VIEWS.room.sendReaction.replyTo.message.editedAt", "result.deleteMessage.requestId", "result.deleteMessage.version", "result.deleteMessage.message.earlierVersions", "result.deleteMessage.message.replyTo.message.earlierVersions", "result.deleteMessage.message.replyTo.message.editedAt", "result.deleteMessage.replyTo.message.earlierVersions", "result.deleteMessage.replyTo.message.editedAt", "result.deleteReaction.requestId", "result.deleteReaction.version", "result.deleteReaction.message.earlierVersions", "result.deleteReaction.message.replyTo.message.earlierVersions", "result.deleteReaction.message.replyTo.message.editedAt", "result.deleteReaction.replyTo.message.earlierVersions", "result.deleteReaction.replyTo.message.editedAt", "result.editMessage.requestId", "result.editMessage.version", "result.editMessage.message.earlierVersions", "result.editMessage.message.replyTo.message.earlierVersions", "result.editMessage.message.replyTo.message.editedAt", "result.editMessage.replyTo.message.earlierVersions", "result.editMessage.replyTo.message.editedAt", "result.messages.openWindow", "result.messages.latest.messages[].earlierVersions", "result.messages.latest.messages[].replyTo.message.earlierVersions", "result.messages.latest.messages[].replyTo.message.editedAt", "result.obliterateMessage.requestId", "result.obliterateMessage.version", "result.obliterateMessage.message.earlierVersions", "result.obliterateMessage.message.replyTo.message.earlierVersions", "result.obliterateMessage.message.replyTo.message.editedAt", "result.obliterateMessage.replyTo.message.earlierVersions", "result.obliterateMessage.replyTo.message.editedAt", "result.participantEntries", "result.participantPrincipals", "result.sendMessage.requestId", "result.sendMessage.version", "result.sendMessage.message.earlierVersions", "result.sendMessage.message.replyTo.message.earlierVersions", "result.sendMessage.message.replyTo.message.editedAt", "result.sendMessage.replyTo.message.earlierVersions", "result.sendMessage.replyTo.message.editedAt", "result.sendReaction.requestId", "result.sendReaction.version", "result.sendReaction.message.earlierVersions", "result.sendReaction.message.replyTo.message.earlierVersions", "result.sendReaction.message.replyTo.message.editedAt", "result.sendReaction.replyTo.message.earlierVersions", "result.sendReaction.replyTo.message.editedAt", "result.$VIEWS.room.messages.threads[].root.earlierVersions", "result.$VIEWS.room.messages.threads[].root.replyTo.message.earlierVersions", "result.$VIEWS.room.messages.threads[].root.replyTo.message.editedAt", "result.messages.threads[].root.earlierVersions", "result.messages.threads[].root.replyTo.message.earlierVersions", "result.messages.threads[].root.replyTo.message.editedAt", ], reason: "a room's messages are objects pushed onto the list under a policy naming the new handlers, and its per-user act outcomes are gone; rooms holding the keyed records are left behind" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-pushed-messages-break.md", }, { // The same break, against the baselines that offered `closeWindow` at the // room's top level; the room offers no windows. pattern: "fabrichat/room.tsx", baselines: [ "20261014T140128Z-95MKWhVw3ffYhuDn", "20261014T151858Z-e6AvrFyYi8qb50yc", "20261014T152002Z-S3S_T8pKGJ3XD0x_", "20261014T162032Z-VqHxNEaxFBSWRpKw", "20261014T173537Z-M6YKFg0N7b8Maarr", "20261014T205901Z-5YIaRjVJC-zB1yRC", "20261014T213629Z-w4GAFScO-yqWGIjk", "20261014T215835Z-JQgYDEHDYD8Vx1AY", "20261014T220435Z-JQgYDEHDYD8Vx1AY", "20261015T011425Z-mx7tYDWFp1_T-wuZ", "20261015T031259Z-18lMcHoeN5ytgVIF", "20261015T180605Z-LucQidGJVpPHBLuf", "20261015T190131Z-YWG2w2gfAFgIl6Fu", "20261015T191100Z-4FcaX32yJN3zm_ei", "20261015T201432Z-VBeuOsAwek05bCb6", "20261015T220631Z-LjNm9_TjufQjzcNb", "20261015T233043Z-sD47t42zpmQ9uLO-", "20261015T233734Z-4o9kkrF1-4iWtsjg", "20261016T001006Z-tkXuT3MmjsJ8Q9ut", "20261015T211659Z-FIqM03M6AFq1f-yc", "20261015T213453Z-WcfKJe6yCq6hHrKo", "20261015T222422Z-gG3vXM2YlJWsGFve", "20261015T230231Z-X4fbcCTNwmTh1D4M", "20261016T004427Z-FEcfxYg99ADYSy58", "20261016T130413Z-IjgiKFLGlXaYMQ9O", "20261016T142642Z-FwoDtgccmQ6x6E51", "20261016T144813Z-j7kfnbuq3vl_PTT8", "20261016T145511Z-URDigmceiHUQTgYw", "20261016T151336Z-qyuKzPzUZ0f_x9H1", ], paths: [ "argument.messages[]", "result.closeWindow", "result.messageRequests", "result.recentActivity", "result.$VIEWS.room.closeWindow", "result.$VIEWS.room.messageRequests", "result.$VIEWS.room.recentActivity", "result.$VIEWS.room.deleteMessage.message.reactions[]", "result.$VIEWS.room.deleteMessage.message.replyTo.message.reactions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteMessage.replyTo.message.reactions", "result.$VIEWS.room.deleteMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteReaction.message.reactions[]", "result.$VIEWS.room.deleteReaction.message.replyTo.message.reactions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.replyTo.message", "result.$VIEWS.room.deleteReaction.replyTo.message.reactions", "result.$VIEWS.room.deleteReaction.replyTo.message.replyTo.message", "result.$VIEWS.room.editMessage.message.reactions[]", "result.$VIEWS.room.editMessage.message.replyTo.message.reactions", "result.$VIEWS.room.editMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.editMessage.replyTo.message.reactions", "result.$VIEWS.room.editMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.messages.closeWindow", "result.$VIEWS.room.messages.windows", "result.$VIEWS.room.messages.latest.messages[].reactions[]", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.reactions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.replyTo.message", "result.$VIEWS.room.messages.threads[].root.reactions[]", "result.$VIEWS.room.messages.threads[].root.replyTo.message.reactions", "result.$VIEWS.room.messages.threads[].root.replyTo.message.replyTo.message", "result.$VIEWS.room.obliterateMessage.message.reactions[]", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.reactions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.obliterateMessage.replyTo.message.reactions", "result.$VIEWS.room.obliterateMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.sendMessage.message.reactions[]", "result.$VIEWS.room.sendMessage.message.replyTo.message.reactions", "result.$VIEWS.room.sendMessage.message.replyTo.message.replyTo.message", "result.$VIEWS.room.sendMessage.replyTo.message.reactions", "result.$VIEWS.room.sendMessage.replyTo.message.replyTo.message", "result.$VIEWS.room.sendReaction.message.reactions[]", "result.$VIEWS.room.sendReaction.message.replyTo.message.reactions", "result.$VIEWS.room.sendReaction.message.replyTo.message.replyTo.message", "result.$VIEWS.room.sendReaction.replyTo.message.reactions", "result.$VIEWS.room.sendReaction.replyTo.message.replyTo.message", "result.deleteMessage.message.reactions[]", "result.deleteMessage.message.replyTo.message.reactions", "result.deleteMessage.message.replyTo.message.replyTo.message", "result.deleteMessage.replyTo.message.reactions", "result.deleteMessage.replyTo.message.replyTo.message", "result.deleteReaction.message.reactions[]", "result.deleteReaction.message.replyTo.message.reactions", "result.deleteReaction.message.replyTo.message.replyTo.message", "result.deleteReaction.replyTo.message.reactions", "result.deleteReaction.replyTo.message.replyTo.message", "result.editMessage.message.reactions[]", "result.editMessage.message.replyTo.message.reactions", "result.editMessage.message.replyTo.message.replyTo.message", "result.editMessage.replyTo.message.reactions", "result.editMessage.replyTo.message.replyTo.message", "result.messages.closeWindow", "result.messages.windows", "result.messages.latest.messages[].reactions[]", "result.messages.latest.messages[].replyTo.message.reactions", "result.messages.latest.messages[].replyTo.message.replyTo.message", "result.messages.threads[].root.reactions[]", "result.messages.threads[].root.replyTo.message.reactions", "result.messages.threads[].root.replyTo.message.replyTo.message", "result.obliterateMessage.message.reactions[]", "result.obliterateMessage.message.replyTo.message.reactions", "result.obliterateMessage.message.replyTo.message.replyTo.message", "result.obliterateMessage.replyTo.message.reactions", "result.obliterateMessage.replyTo.message.replyTo.message", "result.sendMessage.message.reactions[]", "result.sendMessage.message.replyTo.message.reactions", "result.sendMessage.message.replyTo.message.replyTo.message", "result.sendMessage.replyTo.message.reactions", "result.sendMessage.replyTo.message.replyTo.message", "result.sendReaction.message.reactions[]", "result.sendReaction.message.replyTo.message.reactions", "result.sendReaction.message.replyTo.message.replyTo.message", "result.sendReaction.replyTo.message.reactions", "result.sendReaction.replyTo.message.replyTo.message", "result.$VIEWS.room.messageRights[].message.reactions[]", "result.$VIEWS.room.messageRights[].message.replyTo.message.reactions", "result.$VIEWS.room.messageRights[].message.replyTo.message.replyTo.message", "result.messageRights[].message.reactions[]", "result.messageRights[].message.replyTo.message.reactions", "result.messageRights[].message.replyTo.message.replyTo.message", // The paths from here on are recorded in // `docs/history/pattern-compat-every-issue-paths.md`, which names the // recorded change each one comes from. "result.openWindow", "result.recentActivityExpiredThrough", "result.$VIEWS.room.openWindow", "result.$VIEWS.room.recentActivityExpiredThrough", "result.$VIEWS.room.deleteMessage.requestId", "result.$VIEWS.room.deleteMessage.version", "result.$VIEWS.room.deleteMessage.message.earlierVersions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.deleteMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteMessage.replyTo.message.editedAt", "result.$VIEWS.room.deleteReaction.requestId", "result.$VIEWS.room.deleteReaction.version", "result.$VIEWS.room.deleteReaction.message.earlierVersions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteReaction.message.replyTo.message.editedAt", "result.$VIEWS.room.deleteReaction.replyTo.message.earlierVersions", "result.$VIEWS.room.deleteReaction.replyTo.message.editedAt", "result.$VIEWS.room.editMessage.requestId", "result.$VIEWS.room.editMessage.version", "result.$VIEWS.room.editMessage.message.earlierVersions", "result.$VIEWS.room.editMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.editMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.editMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.editMessage.replyTo.message.editedAt", "result.$VIEWS.room.messages.openWindow", "result.$VIEWS.room.messages.latest.messages[].earlierVersions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.earlierVersions", "result.$VIEWS.room.messages.latest.messages[].replyTo.message.editedAt", "result.$VIEWS.room.messages.threads[].root.earlierVersions", "result.$VIEWS.room.messages.threads[].root.replyTo.message.earlierVersions", "result.$VIEWS.room.messages.threads[].root.replyTo.message.editedAt", "result.$VIEWS.room.obliterateMessage.requestId", "result.$VIEWS.room.obliterateMessage.version", "result.$VIEWS.room.obliterateMessage.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.obliterateMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.obliterateMessage.replyTo.message.editedAt", "result.$VIEWS.room.participantEntries", "result.$VIEWS.room.participantPrincipals", "result.$VIEWS.room.sendMessage.requestId", "result.$VIEWS.room.sendMessage.version", "result.$VIEWS.room.sendMessage.message.earlierVersions", "result.$VIEWS.room.sendMessage.message.replyTo.message.earlierVersions", "result.$VIEWS.room.sendMessage.message.replyTo.message.editedAt", "result.$VIEWS.room.sendMessage.replyTo.message.earlierVersions", "result.$VIEWS.room.sendMessage.replyTo.message.editedAt", "result.$VIEWS.room.sendReaction.requestId", "result.$VIEWS.room.sendReaction.version", "result.$VIEWS.room.sendReaction.message.earlierVersions", "result.$VIEWS.room.sendReaction.message.replyTo.message.earlierVersions", "result.$VIEWS.room.sendReaction.message.replyTo.message.editedAt", "result.$VIEWS.room.sendReaction.replyTo.message.earlierVersions", "result.$VIEWS.room.sendReaction.replyTo.message.editedAt", "result.deleteMessage.requestId", "result.deleteMessage.version", "result.deleteMessage.message.earlierVersions", "result.deleteMessage.message.replyTo.message.earlierVersions", "result.deleteMessage.message.replyTo.message.editedAt", "result.deleteMessage.replyTo.message.earlierVersions", "result.deleteMessage.replyTo.message.editedAt", "result.deleteReaction.requestId", "result.deleteReaction.version", "result.deleteReaction.message.earlierVersions", "result.deleteReaction.message.replyTo.message.earlierVersions", "result.deleteReaction.message.replyTo.message.editedAt", "result.deleteReaction.replyTo.message.earlierVersions", "result.deleteReaction.replyTo.message.editedAt", "result.editMessage.requestId", "result.editMessage.version", "result.editMessage.message.earlierVersions", "result.editMessage.message.replyTo.message.earlierVersions", "result.editMessage.message.replyTo.message.editedAt", "result.editMessage.replyTo.message.earlierVersions", "result.editMessage.replyTo.message.editedAt", "result.messages.openWindow", "result.messages.latest.messages[].earlierVersions", "result.messages.latest.messages[].replyTo.message.earlierVersions", "result.messages.latest.messages[].replyTo.message.editedAt", "result.messages.threads[].root.earlierVersions", "result.messages.threads[].root.replyTo.message.earlierVersions", "result.messages.threads[].root.replyTo.message.editedAt", "result.obliterateMessage.requestId", "result.obliterateMessage.version", "result.obliterateMessage.message.earlierVersions", "result.obliterateMessage.message.replyTo.message.earlierVersions", "result.obliterateMessage.message.replyTo.message.editedAt", "result.obliterateMessage.replyTo.message.earlierVersions", "result.obliterateMessage.replyTo.message.editedAt", "result.participantEntries", "result.participantPrincipals", "result.sendMessage.requestId", "result.sendMessage.version", "result.sendMessage.message.earlierVersions", "result.sendMessage.message.replyTo.message.earlierVersions", "result.sendMessage.message.replyTo.message.editedAt", "result.sendMessage.replyTo.message.earlierVersions", "result.sendMessage.replyTo.message.editedAt", "result.sendReaction.requestId", "result.sendReaction.version", "result.sendReaction.message.earlierVersions", "result.sendReaction.message.replyTo.message.earlierVersions", "result.sendReaction.message.replyTo.message.editedAt", "result.sendReaction.replyTo.message.earlierVersions", "result.sendReaction.replyTo.message.editedAt", "result.$VIEWS.room.messageRights[].message.earlierVersions", "result.$VIEWS.room.messageRights[].message.replyTo.message.earlierVersions", "result.$VIEWS.room.messageRights[].message.replyTo.message.editedAt", "result.messageRights[].message.earlierVersions", "result.messageRights[].message.replyTo.message.earlierVersions", "result.messageRights[].message.replyTo.message.editedAt", ], reason: "a room's messages are objects pushed onto the list under a policy naming the new handlers, and its message windows are gone; rooms holding the keyed records are left behind" + "; the further paths it names are recorded in docs/history/pattern-compat-every-issue-paths.md", record: "docs/history/fabrichat-pushed-messages-break.md", }, { // A placement no longer passes the room's activity log through, since // the room keeps none. pattern: "fabrichat/placement.tsx", baselines: [ "20261002T164437Z-YHxasJyb9fC8x4pe", "20261013T211911Z-zT2_vHqj25wS-uwm", ], paths: [ "result.$VIEWS.chat.recentActivity", "result.$VIEWS.chat.messages.windows", "result.room.recentActivity", "result.room.messages.windows", ], reason: "the room keeps no activity log, so the placement's data face no longer carries one", record: "docs/history/fabrichat-pushed-messages-break.md", }, { // The adapter re-exports the placement's data face, so it loses the same // field. pattern: "fabrichat/adapter.tsx", baselines: [ "20261002T164437Z-2PzF8f6WgNbffWBh", "20261013T211911Z-ucRdNCI0HJOQ7XAv", ], paths: [ "result.$VIEWS.chat.recentActivity", "result.$VIEWS.chat.messages.windows", "result.placement.$VIEWS.chat.recentActivity", "result.placement.$VIEWS.chat.messages.windows", "result.placement.room.recentActivity", "result.placement.room.messages.windows", ], reason: "the room keeps no activity log, so the data face the adapter re-exports no longer carries one", record: "docs/history/fabrichat-pushed-messages-break.md", }, { // A pick was a required link to a held finished book, so every valid // result was five rereads. A pick is the recommended book inline now, // with an optional link to the finished book it builds on. pattern: "book-recommendations/main.tsx", baselines: [ "20260920T171659Z-3vmp5U6KQQHIKzya", "20261004T000822Z-RG9CkXhT9Y8zMON8", ], paths: ["result.recommendation.result"], reason: "a pick is the recommended book inline with an optional `basedOn` link, where the recorded result required a `book` link to a finished book", record: "docs/history/book-recommendations-picks-break.md", }, { // The seeded demo composes the pattern and returns its result. pattern: "book-recommendations/seeded-live-demo.tsx", baselines: [ "20260922T074703Z-x2D--ODNVd-Doeie", "20261004T000822Z-Uae2gNquN1m1hysE", ], paths: ["result.recommendation.result"], reason: "a pick is the recommended book inline with an optional `basedOn` link, where the recorded result required a `book` link to a finished book", record: "docs/history/book-recommendations-picks-break.md", }, { // The view takes the state it displays as an argument and returns it, // so the pick's new shape shows on both faces. pattern: "book-recommendations/view.tsx", baselines: ["20260920T171659Z-uSukTQQPKBcQgQSk"], paths: [ "argument.state.result.picks[].title", "result.state.result.picks[].book", "argument.state.result.picks[].author", ], reason: "a pick carries `title`, `author` and `why` inline and `basedOn` in place of `book`", record: "docs/history/book-recommendations-picks-break.md", }, { // The manager's views derived under the reader's access (`rooms`, // `people`) are declared per user where they were declared per session. // The proof reads that as a changed scope at each. The baselines that // also report the room policy's `maxAttachments` are in that break's // entry, which names both paths. pattern: "fabrichat/manager.tsx", baselines: [ "20261024T000755Z-abyOKppwBZufFk_m", ], paths: [ "result.$VIEWS.chats.people", "result.$VIEWS.chats.rooms", "result.people", "result.rooms", ], reason: "the manager's views derived under the reader's access are stored per user rather than per session, in documents of their own; a manager rolled forward lists its rooms", record: "docs/history/fabrichat-view-scopes-per-user-break.md", }, { // The room's `participantEntries` and `participantPrincipals` are // declared per user where they were declared per session. pattern: "fabrichat/room.tsx", baselines: [ "20261016T053638Z-KQKz6B5ir-i_b2SS", "20261016T153436Z-pRy5c_bxbuVZdFhZ", "20261016T163240Z-VzSSk0EfxY0KC9hS", "20261016T164542Z-Og9yZmA1u5WeXwCN", "20261016T165510Z-vsc_lFnf0kuiGOzM", "20261016T171911Z-UsM9ehwli7eo6Otm", "20261016T174740Z-dgRxrNv4zwPax9H2", "20261016T183810Z-M-epGFTqdJCXqpdY", "20261016T184531Z-gbZC3T21TeTxRvo-", "20261016T193302Z-sc2O1lFUsZPJ_mQb", "20261016T230431Z-g8_CPlpZxyagr5NX", "20261016T232234Z-thh7FfVQXJz1jvma", "20261016T234919Z-CoEadoaDhwXNTNly", "20261018T030554Z-M6esswMg1IIMlLJ1", "20261018T072351Z--tm-zMdGue1lcFC9", "20261018T181024Z-8qQmq6MV1Ik7_eO5", "20261019T231845Z-Vj5dqYA2toFthDOE", "20261022T220214Z-LuSDquW0A2n4QZ8w", "20261023T213239Z-wQjScvFleK2bL80b", "20261024T000756Z-dKtPP_2-Aa_KMMvf", "20261024T003401Z-xURqZ9DluSiRDXhB", "20261024T014452Z-fKwRjY5cCkMEpatS", "20261024T022151Z-IsyaJEIMyiypxAgF", "20261024T022626Z-fQTNhQDagiuXxPOO", "20261024T145618Z-Gv5sfeYUA8vf1ZMN", ], paths: [ "result.$VIEWS.room.participantEntries", "result.$VIEWS.room.participantPrincipals", "result.participantEntries", "result.participantPrincipals", ], reason: "the room's participant entries and principals are stored per user rather than per session, in documents of their own; a room rolled forward lists them", record: "docs/history/fabrichat-view-scopes-per-user-break.md", }, { // Home types its `chatManager` as the manager's output, so the manager's // per-user `people` reaches home's contract too. Home is a required // pattern, so it carries the ruling that lets it name one. pattern: "system/home.tsx", baselines: [ "20261011T232406Z-H8GLTyEEvgcBxdB1", "20261012T052420Z-12t_tpKxi8VbviJa", "20261012T173537Z-qa-uVwDf1s3biqH0", "20261013T181949Z-GBuQOV7gSSM47_32", "20261014T011647Z-MFMywpgMEY_E99SW", "20261014T030848Z-JisMyyIiJIrCf4Gb", "20261014T040623Z-Dv8vGrR_RU4o_od4", "20261014T114259Z-bqtp-2EzUZZiWqbT", "20261014T162033Z-LIoQs5Jl8gnJGhKC", "20261015T201353Z-oCK_qi6_rPitM38o", "20261015T211701Z-H-GPmz8jSVGzuo_8", "20261016T130414Z-85KSXDBnUvxPHW1X", "20261016T131539Z-pViYLhxUrHjY4Ns0", "20261016T150229Z-pLkLhdLf5j1OaZ12", "20261016T163241Z-dI5NsGutavMFOaTh", "20261016T232237Z-1-QwrXrbROaZhlyk", "20261016T235217Z-vOAvtNyhZ8DRhyJx", "20261018T005038Z-gFqm7i0HKcxGUI-b", "20261018T181025Z-DNDWDmf6635D93ez", "20261019T231846Z-a4jCOmx9encoFZ6S", "20261022T203735Z-VmCROm_UqDxFqhqv", "20261022T220216Z-drGbEASF5X5lV4en", "20261023T225638Z-ul8itnlMjhVPl5G4", "20261024T000758Z-cjuKEPPeYWQzIxGW", ], paths: [ "result.chatManager.$VIEWS.chats.people", "result.chatManager.$VIEWS.chats.rooms", "result.chatManager.people", "result.chatManager.rooms", ], reason: "home's chat manager's views derived under the reader's access are stored per user rather than per session; a home rolled forward lists its chats", record: "docs/history/fabrichat-view-scopes-per-user-break.md", requiredPatternOverride: { rulingBy: "Dan", on: "2026-10-23", reason: "choosing per-user scopes for FabriChat's derived views, with binding renames giving them documents of their own so a home rolled forward keeps listing its chats, and accepting the warnings an update logs once per view as it opens each piece", }, }, ];