@knkcs/contenthub-ui 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +3 -3
- package/dist/{branch-content-fields-BQG6U0yl.js → branch-content-fields-DI9aQfh0.js} +2 -2
- package/dist/{branch-content-fields-BQG6U0yl.js.map → branch-content-fields-DI9aQfh0.js.map} +1 -1
- package/dist/{content-library-DFIk09bD.js → content-library-BdHuzmXL.js} +160 -14
- package/dist/content-library-BdHuzmXL.js.map +1 -0
- package/dist/{heads-DqHmAW0n.js → heads-BrvZ_GYT.js} +4 -3
- package/dist/heads-BrvZ_GYT.js.map +1 -0
- package/dist/index.d.ts +450 -13
- package/dist/index.js +3261 -2533
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +155 -7
- package/dist/testing.js +551 -317
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
- package/dist/content-library-DFIk09bD.js.map +0 -1
- package/dist/heads-DqHmAW0n.js.map +0 -1
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","names":["GuardianModeRequiredError","PublishRefusedError","NameTakenError","WithheldWorkError","StaleHeadError","StaleStatusError","StatusTransitionRefusedError","EditingModeRefusedError","MAX_BLUEPRINT_IDS","ContentArchivedError","CoversReleaseError","CHECK_NOTE_MAX","CheckResultDeniedError","ChangeSetClosedError","inForceOnOrAfter","RestrictionUnavailableError","sameHeads","releaseInForceOn","DAY","AccessDeniedError","headsOf","BlockReasonNameTakenError","ContentBlockedError","InvalidInputError","DirectEditRefusedError","ContentRefusedError","STUB_WORKSPACE_ID","STUB_USER_ID","STUB_OTHER_USER_ID","STUB_NOW","stubIdentity","createHostMembers","stubBlockReasons","stubChangeSetStatuses","stubStatusTransitions","stubChangeSets","stubRequiredChecks","stubCollections","stubBlueprints","stubBlueprintReleases","stubResolvedReleases","text","accessor","paragraph","stubUndatedContent","at","stubRepealedContent","stubContents","createStubBlueprintSource","q","query","blueprints","b","ids","releases","r","blueprintId","shiftDay","d","day","by","oneLine","value","raw","what","max","checkedSourceOf","source","checkedBlockReasonName","name","checkedRequiredCheck","input","accessors","a","RECORDERS_WORKSPACE_MODE","WITHHELD_REFUSAL","WORKSPACE_MODE_REFUSAL","notFound","ConnectError","id","Code","copy","cs","stubBlocker","fields","createStubContenthubClient","now","options","userId","statuses","transitions","reasons","changeSets","collections","c","contents","resolved","requiredChecks","authzMode","withheld","refuseWithheld","grants","recorders","recordersOf","checkId","memberIds","admin","workspaceEditing","editingOverrides","effectiveOf","o","overrideOut","editingModes","adminOnly","checkResults","extraBlockers","pendingMerges","conflicts","stored","wroteUnder","once","key","write","asked","request","kept","answer","publishedWith","savedUnder","next","findContent","each","attributesOf","today","datedContent","revisionsOf","listed","heads","csId","h","dataOf","revisionId","missingRequired","unset","v","f","values","checkEditable","gapReferrersOf","other","e","contentId","byName","taken","except","collectionOrder","findCollection","siblingNamed","parentId","manageable","owns","g","narrowable","saveOnce","chain","open","changeSetId","ch","branchId","branch","expectedHeadId","head","sent","data","saved","fieldMask","stray","k","writeHead","createTime","branchIn","storeMerge","pm","conflict","dropMerge","checkPlan","vp","plan","violations","covered","repropose","previous","p","proposals","propose","same","splitFromReleaseId","its","find","statusName","s","slug","reaches","from","to","seen","subjectsOf","pr","blueprintOf","covers","check","standingsOf","subjects","resultsOn","subject","_","standing","latest","results","stale","out","byNameThenId","blockersOf","current","reviewed","dep","state","st","x","releasesOf","client","reason","matching","size","start","rawName","checkedSource","updateMask","nextName","nextSource","expectedStatus","status","assigneeIds","target","dependsOnId","published","reviewedHeads","blockers","cut","idempotencyKey","releaseId","validityPeriod","changeSetName","timeline","entry","firstDay","lastDay","override","plannedRelease","chainId","chains","conflicted","pending","ref","outcome","note","requiredCheckId","recording","named","result","byAccessor","blueprintAccessor","settings","editingMode","editingBlock","checked","held","recorder","u","restricted","collection","unfiled","acknowledgeDisclosure","collectionId","grantee","level","view","search","rows","readsOf","blueprintReleaseId","copyFrom","sourceRevision","release","n","content","rev","isOpen","found","owner","pageSize","pageToken","_data","all","after","baseId","base","before","changes","strip","page","fromReleases","includeOpenChangeSets","fromBranches","inForce","unique","collectionIds","col","blockReasonId","allowedUserIds","mine","mode","started","main","effectiveOn","label","entries","fork","releaseSpec","supersedesReleaseIds","plannedReleaseId","updated","last","tip","paths","resolutions","validOn","row","matches","hits","fold","needle","createStubStatusSource"],"sources":["../src/testing/fixtures.ts","../src/testing/stub-blueprint-source.ts","../src/testing/stub-client.ts","../src/testing/stub-status-source.ts"],"sourcesContent":["import { createHostMembers, type HostIdentity } from \"@knkcs/anker/host\";\nimport type {\n\tBlockReason,\n\tBlueprintInfo,\n\tBlueprintReleaseInfo,\n\tChangeSet,\n\tChangeSetStatusInfo,\n\tCollection,\n\tContentBlock,\n\tEdge,\n\tPlannedRelease,\n\tRequiredCheck,\n\tResolvedBlueprintRelease,\n\tResolvedField,\n\tRevision,\n\tTimelineEntry,\n} from \"../types\";\n\nexport const STUB_WORKSPACE_ID = \"ws_stub\";\nexport const STUB_USER_ID = \"user_stub\";\n/** A second member of the stub workspace, to assign and filter by. */\nexport const STUB_OTHER_USER_ID = \"user_ben\";\nexport const STUB_NOW = \"2026-10-01T09:00:00.000Z\";\n\n/** Who is looking, for anker's `TestHost` or `<HostProvider identity>`. */\nexport function stubIdentity(): HostIdentity {\n\treturn {\n\t\tuserId: STUB_USER_ID,\n\t\tworkspaceId: STUB_WORKSPACE_ID,\n\t\tmembers: createHostMembers([\n\t\t\t{ userId: STUB_USER_ID, displayName: \"Ada Editor\", email: \"ada@example.com\" },\n\t\t\t{ userId: STUB_OTHER_USER_ID, displayName: \"Ben Reviewer\", email: \"ben@example.com\" },\n\t\t]),\n\t};\n}\n\n/** A legal publisher's Block Reasons, in the service's order (by name). */\nexport function stubBlockReasons(): BlockReason[] {\n\treturn [\n\t\t{\n\t\t\tid: \"br_author\",\n\t\t\tname: \"Being revised by the author\",\n\t\t\tcreateTime: STUB_NOW,\n\t\t\tupdateTime: STUB_NOW,\n\t\t},\n\t\t{\n\t\t\tid: \"br_embargo\",\n\t\t\tname: \"Embargoed until publication\",\n\t\t\tcreateTime: STUB_NOW,\n\t\t\tupdateTime: STUB_NOW,\n\t\t},\n\t];\n}\n\n/**\n * statushub's seed catalogue for `contenthub/change_set` (spec #56, story 9),\n * as the `StatusSource` port answers it. Colours are CSS names: statushub\n * holds whatever CSS colour an admin chose.\n */\nexport function stubChangeSetStatuses(): ChangeSetStatusInfo[] {\n\treturn [\n\t\t{ slug: \"in_progress\", name: \"In Bearbeitung\", color: \"steelblue\", isDefault: true },\n\t\t{ slug: \"in_review\", name: \"In Prüfung\", color: \"orange\" },\n\t\t{ slug: \"ready\", name: \"Bereit\", color: \"seagreen\" },\n\t\t{ slug: \"on_hold\", name: \"Zurückgestellt\", color: \"gray\" },\n\t];\n}\n\n/**\n * The moves the stub's statushub allows, from slug to slugs. Anything else is\n * refused with a reason, as statushub refuses it; a move away from an unknown\n * status is never checked (contenthub ADR 0014).\n */\nexport function stubStatusTransitions(): Record<string, string[]> {\n\treturn {\n\t\tin_progress: [\"in_review\", \"on_hold\"],\n\t\tin_review: [\"in_progress\", \"ready\", \"on_hold\"],\n\t\tready: [\"in_review\", \"on_hold\"],\n\t\ton_hold: [\"in_progress\"],\n\t};\n}\n\n/**\n * A gazette's Change Sets: one open with two Chains (§ 1 amended twice, so\n * two Branches, and a paragraph born in it), one open with nothing in it yet,\n * and one published correction. Newest first, as the service lists them.\n */\nexport function stubChangeSets(): ChangeSet[] {\n\treturn [\n\t\t{\n\t\t\tid: \"cs_bgbl_270\",\n\t\t\tname: \"BGBl. 2026 I Nr. 270\",\n\t\t\tsource: { date: \"2026-09-20\", reference: \"BGBl. 2026 I Nr. 270\" },\n\t\t\tstate: \"open\",\n\t\t\tcreatedBy: STUB_USER_ID,\n\t\t\tcreateTime: \"2026-09-30T08:00:00.000Z\",\n\t\t\tchains: [\n\t\t\t\t{\n\t\t\t\t\tid: \"chain_para_1\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tborn: false,\n\t\t\t\t\tbranches: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"br_para_1_a\",\n\t\t\t\t\t\t\tposition: 0,\n\t\t\t\t\t\t\tkind: \"editorial\",\n\t\t\t\t\t\t\theadRevisionId: \"rev_p1_a2\",\n\t\t\t\t\t\t\teffectiveOn: \"2026-07-01\",\n\t\t\t\t\t\t\tcarriedReleaseId: \"rls_p1_1\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"br_para_1_b\",\n\t\t\t\t\t\t\tposition: 1,\n\t\t\t\t\t\t\tkind: \"editorial\",\n\t\t\t\t\t\t\theadRevisionId: \"rev_p1_b1\",\n\t\t\t\t\t\t\teffectiveOn: \"2026-10-01\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"chain_para_4a\",\n\t\t\t\t\tcontentId: \"content_para_4a\",\n\t\t\t\t\tborn: true,\n\t\t\t\t\tbranches: [\n\t\t\t\t\t\t{ id: \"br_para_4a\", position: 0, kind: \"editorial\", headRevisionId: \"rev_p4a_1\" },\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t\tdependsOnChangeSetIds: [],\n\t\t\tstatus: \"in_progress\",\n\t\t\tassigneeIds: [STUB_USER_ID],\n\t\t\tplannedReleases: [\n\t\t\t\t{\n\t\t\t\t\tid: \"rls_p1_2\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\tbranchId: \"br_para_1_b\",\n\t\t\t\t\trevisionId: \"\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"2026-10-01\", lastDay: \"\" },\n\t\t\t\t\tsupersedesReleaseIds: [],\n\t\t\t\t\tproposed: false,\n\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\twithheld: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t// The cut ending § 1's Release In Force the day before the\n\t\t\t\t\t// amendment starts: proposed, never planned by hand.\n\t\t\t\t\tid: \"rls_p1_1_cut\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tkind: \"date_only\",\n\t\t\t\t\tbranchId: \"\",\n\t\t\t\t\trevisionId: \"rev_p1_main\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"2020-01-01\", lastDay: \"2026-09-30\" },\n\t\t\t\t\tsupersedesReleaseIds: [\"rls_p1_1\"],\n\t\t\t\t\tproposed: true,\n\t\t\t\t\tproposedForReleaseId: \"rls_p1_1\",\n\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\twithheld: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"rls_p4a_1\",\n\t\t\t\t\tcontentId: \"content_para_4a\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\tbranchId: \"br_para_4a\",\n\t\t\t\t\trevisionId: \"\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"2026-10-01\", lastDay: \"\" },\n\t\t\t\t\tsupersedesReleaseIds: [],\n\t\t\t\t\tproposed: false,\n\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\twithheld: false,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tid: \"cs_bgbl_255\",\n\t\t\tname: \"BGBl. 2026 I Nr. 255\",\n\t\t\tsource: { date: \"2026-09-10\", reference: \"BGBl. 2026 I Nr. 255\" },\n\t\t\tstate: \"open\",\n\t\t\tcreatedBy: STUB_OTHER_USER_ID,\n\t\t\tcreateTime: \"2026-09-25T08:00:00.000Z\",\n\t\t\tchains: [],\n\t\t\tdependsOnChangeSetIds: [],\n\t\t\tstatus: \"\",\n\t\t\tassigneeIds: [STUB_OTHER_USER_ID],\n\t\t\tplannedReleases: [],\n\t\t},\n\t\t{\n\t\t\tid: \"cs_correction_3\",\n\t\t\tname: \"Correction of § 3\",\n\t\t\tstate: \"published\",\n\t\t\tcreatedBy: STUB_USER_ID,\n\t\t\tcreateTime: \"2026-09-01T08:00:00.000Z\",\n\t\t\tcloseTime: \"2026-09-02T08:00:00.000Z\",\n\t\t\tchains: [],\n\t\t\tdependsOnChangeSetIds: [],\n\t\t\tstatus: \"ready\",\n\t\t\tassigneeIds: [],\n\t\t\tplannedReleases: [],\n\t\t},\n\t];\n}\n\n/**\n * A legal publisher's Required Checks, by name: a print round trip once per\n * Change Set, and a lawyer's review of each Branch, by someone who wrote\n * none of it. Both apply to every Blueprint.\n */\nexport function stubRequiredChecks(): RequiredCheck[] {\n\treturn [\n\t\t{\n\t\t\tid: \"rc_print\",\n\t\t\tname: \"Druckprobe\",\n\t\t\tscope: \"change_set\",\n\t\t\tblueprintAccessors: [],\n\t\t\tindependent: false,\n\t\t},\n\t\t{\n\t\t\tid: \"rc_lawyer\",\n\t\t\tname: \"Juristische Prüfung\",\n\t\t\tscope: \"branch\",\n\t\t\tblueprintAccessors: [],\n\t\t\tindependent: true,\n\t\t},\n\t];\n}\n\n/**\n * A legal publisher's Collection tree, by name as the service lists it:\n * Laws holding BGB and StGB, and Commentary beside it.\n */\nexport function stubCollections(): Collection[] {\n\treturn [\n\t\t{ id: \"col_bgb\", name: \"BGB\", parentId: \"col_laws\", restricted: false },\n\t\t{ id: \"col_commentary\", name: \"Commentary\", parentId: \"\", restricted: false },\n\t\t{ id: \"col_laws\", name: \"Laws\", parentId: \"\", restricted: false },\n\t\t{ id: \"col_stgb\", name: \"StGB\", parentId: \"col_laws\", restricted: false },\n\t];\n}\n\n/**\n * The workspace's content Blueprints, as a `BlueprintSource` answers, by\n * name. Commentary has had no Release cut yet, so contenthub's catalog\n * (the stub client's `searchBlueprints`) leaves it out.\n */\nexport function stubBlueprints(): BlueprintInfo[] {\n\treturn [\n\t\t{ id: \"bp_commentary\", name: \"Commentary\" },\n\t\t{ id: \"bp_footnote\", name: \"Footnote\" },\n\t\t{ id: \"bp_paragraph\", name: \"Paragraph\" },\n\t];\n}\n\n/** Their Releases, newest first per Blueprint. */\nexport function stubBlueprintReleases(): BlueprintReleaseInfo[] {\n\treturn [\n\t\t{\n\t\t\tid: \"bpr_paragraph_2\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tname: \"2026-10\",\n\t\t\treleaseTime: \"2026-10-01T07:00:00.000Z\",\n\t\t},\n\t\t{\n\t\t\tid: \"bpr_paragraph_1\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tname: \"2026-09\",\n\t\t\treleaseTime: \"2026-09-01T07:00:00.000Z\",\n\t\t},\n\t\t{\n\t\t\tid: \"bpr_footnote_1\",\n\t\t\tblueprintId: \"bp_footnote\",\n\t\t\tname: \"2026-08\",\n\t\t\treleaseTime: \"2026-08-01T07:00:00.000Z\",\n\t\t},\n\t];\n}\n\n/** One head of a Content: its Revision, data and when it was written. */\nexport interface StubHead {\n\trevisionId: string;\n\tdata: Record<string, unknown>;\n\t/** ISO 8601. */\n\trevisionCreateTime: string;\n}\n\n/**\n * A Content of the stub workspace, every way the screens can read it. Not a\n * service type: it is what the stub keeps to answer its reads.\n */\nexport interface StubContent {\n\tid: string;\n\tblueprintId: string;\n\tblueprintReleaseId: string;\n\t/** The Collections it is filed in, directly. */\n\tcollectionIds: string[];\n\t/** Who maintains it; none when absent. */\n\tassigneeIds?: string[];\n\t/** Its Block; absent while it is not blocked. */\n\tblock?: ContentBlock;\n\t/** When it was archived, ISO 8601; absent while it is not Archived. */\n\tarchiveTime?: string;\n\t/** Its Main head; absent while it was born in an open Change Set. */\n\tmain?: StubHead;\n\t/** The Release In Force today, and the head it pins; absent for none. */\n\tinForce?: StubHead & { releaseId: string };\n\t/** The head of its Chain's last Branch in each Change Set it is in, by Change Set id. */\n\tbranches: Record<string, StubHead & { branchId: string }>;\n\t/** Its Timeline as known now; none when absent. */\n\ttimeline?: TimelineEntry[];\n\t/** What open (or since closed) Change Sets plan for it, in the order planned. */\n\tplannedReleases?: { changeSetId: string; plannedRelease: PlannedRelease }[];\n\t/** Its Revisions, newest first, beyond what its heads imply; none when absent. */\n\trevisions?: (Revision & { data?: Record<string, unknown> })[];\n\t/** The outgoing edges of its Revisions, each naming the Revision holding it. */\n\tedges?: Edge[];\n}\n\n/**\n * The Resolved Releases contenthub holds for the fixtures' Blueprint\n * Releases, by id, as `getContent` decodes them: a paragraph has a number\n * and a heading, a footnote a text. Both are Dated.\n */\nexport function stubResolvedReleases(): Record<string, ResolvedBlueprintRelease> {\n\tconst text = (accessor: string, name: string): ResolvedField => ({\n\t\tfield_type: \"text\",\n\t\tconfig: { name, api_accessor: accessor, required: false, instructions: \"\" },\n\t\tsystem: false,\n\t});\n\tconst paragraph: ResolvedBlueprintRelease = {\n\t\tdisplayName: \"Paragraph\",\n\t\taccessor: \"paragraph\",\n\t\tdated: true,\n\t\tfields: [text(\"number\", \"Number\"), text(\"heading\", \"Heading\")],\n\t\tparts: {},\n\t};\n\treturn {\n\t\tbpr_paragraph_1: paragraph,\n\t\tbpr_paragraph_2: paragraph,\n\t\tbpr_footnote_1: {\n\t\t\tdisplayName: \"Footnote\",\n\t\t\taccessor: \"footnote\",\n\t\t\tdated: true,\n\t\t\tfields: [text(\"text\", \"Text\")],\n\t\t\tparts: {},\n\t\t},\n\t\t// Undated: what a Direct Edit takes (ADR 0022).\n\t\tbpr_note_1: {\n\t\t\tdisplayName: \"Note\",\n\t\t\taccessor: \"note\",\n\t\t\tdated: false,\n\t\t\tfields: [text(\"title\", \"Title\")],\n\t\t\tparts: {},\n\t\t},\n\t};\n}\n\n/**\n * An editorial note, undated and published, whose Blueprint `note` is what a\n * Direct Edit edits (ADR 0022, #264): Dated Content takes none yet. Not among\n * `stubContents()`, so the Library's fixtures stay as they are; pass it in\n * with `contents`, and set the stub's `editingSettings` to offer Edit.\n */\nexport function stubUndatedContent(): StubContent {\n\tconst at = \"2026-09-01T08:00:00.000Z\";\n\treturn {\n\t\tid: \"content_note_1\",\n\t\tblueprintId: \"bp_note\",\n\t\tblueprintReleaseId: \"bpr_note_1\",\n\t\tcollectionIds: [],\n\t\tmain: { revisionId: \"rev_note1_main\", data: { title: \"Hinweis\" }, revisionCreateTime: at },\n\t\tinForce: {\n\t\t\trevisionId: \"rev_note1_main\",\n\t\t\tdata: { title: \"Hinweis\" },\n\t\t\trevisionCreateTime: at,\n\t\t\treleaseId: \"rls_note1_1\",\n\t\t},\n\t\tbranches: {},\n\t\ttimeline: [\n\t\t\t{\n\t\t\t\tordinal: 1,\n\t\t\t\treleaseId: \"rls_note1_1\",\n\t\t\t\tkind: \"revision\",\n\t\t\t\trevisionId: \"rev_note1_main\",\n\t\t\t\tblueprintReleaseId: \"bpr_note_1\",\n\t\t\t\tpublishTime: at,\n\t\t\t\tfirst: true,\n\t\t\t},\n\t\t],\n\t};\n}\n\n/**\n * § 3 BGB, repealed at the end of 2001: published, filed in BGB, with\n * nothing In Force today or later, so it may be archived. Not among\n * `stubContents()`, so the Library's fixtures stay as they are; pass it in\n * with `contents` to a stub that needs it.\n */\nexport function stubRepealedContent(): StubContent {\n\tconst at = \"2001-11-01T08:00:00.000Z\";\n\tconst data = { number: \"§ 3\", heading: \"(weggefallen)\" };\n\treturn {\n\t\tid: \"content_para_3\",\n\t\tblueprintId: \"bp_paragraph\",\n\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\tcollectionIds: [\"col_bgb\"],\n\t\tmain: { revisionId: \"rev_p3_main\", data, revisionCreateTime: at },\n\t\tbranches: {},\n\t\ttimeline: [\n\t\t\t{\n\t\t\t\tordinal: 1,\n\t\t\t\treleaseId: \"rls_p3_repeal\",\n\t\t\t\tkind: \"repeal\",\n\t\t\t\trevisionId: \"rev_p3_main\",\n\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\tvalidityPeriod: { firstDay: \"1900-01-01\", lastDay: \"2001-12-31\" },\n\t\t\t\tpublishTime: at,\n\t\t\t\tfirst: true,\n\t\t\t},\n\t\t],\n\t};\n}\n\n/**\n * The Content behind the fixtures' Change Sets: § 1 BGB, amended in\n * BGBl. 2026 I Nr. 270; § 2 BGB; § 4a BGB, born in that Change Set; § 211\n * StGB; and a footnote filed nowhere, published but with no Release In Force\n * yet (dated to start next year).\n */\nexport function stubContents(): StubContent[] {\n\tconst at = \"2026-09-01T08:00:00.000Z\";\n\treturn [\n\t\t{\n\t\t\tid: \"content_fn_1\",\n\t\t\tblueprintId: \"bp_footnote\",\n\t\t\tblueprintReleaseId: \"bpr_footnote_1\",\n\t\t\tcollectionIds: [],\n\t\t\tmain: {\n\t\t\t\trevisionId: \"rev_fn1_main\",\n\t\t\t\tdata: { text: \"Fassung ab 1. Januar 2027\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tbranches: {},\n\t\t\ttimeline: [\n\t\t\t\t{\n\t\t\t\t\tordinal: 1,\n\t\t\t\t\treleaseId: \"rls_fn1_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\trevisionId: \"rev_fn1_main\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_footnote_1\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"2027-01-01\", lastDay: \"\" },\n\t\t\t\t\tpublishTime: at,\n\t\t\t\t\tfirst: true,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tid: \"content_para_1\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\tcollectionIds: [\"col_bgb\"],\n\t\t\tassigneeIds: [STUB_USER_ID, STUB_OTHER_USER_ID],\n\t\t\tmain: {\n\t\t\t\trevisionId: \"rev_p1_main\",\n\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tinForce: {\n\t\t\t\treleaseId: \"rls_p1_1\",\n\t\t\t\trevisionId: \"rev_p1_main\",\n\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tbranches: {\n\t\t\t\tcs_bgbl_270: {\n\t\t\t\t\tbranchId: \"br_para_1_b\",\n\t\t\t\t\trevisionId: \"rev_p1_b1\",\n\t\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit, Erbfähigkeit\" },\n\t\t\t\t\trevisionCreateTime: \"2026-09-30T09:00:00.000Z\",\n\t\t\t\t},\n\t\t\t},\n\t\t\ttimeline: [\n\t\t\t\t{\n\t\t\t\t\tordinal: 1,\n\t\t\t\t\treleaseId: \"rls_p1_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\trevisionId: \"rev_p1_main\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"1900-01-01\", lastDay: \"\" },\n\t\t\t\t\tpublishTime: at,\n\t\t\t\t\tfirst: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\tplannedReleases: [\n\t\t\t\t{\n\t\t\t\t\tchangeSetId: \"cs_bgbl_270\",\n\t\t\t\t\tplannedRelease: {\n\t\t\t\t\t\tid: \"rls_p1_270\",\n\t\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\t\tbranchId: \"br_para_1_b\",\n\t\t\t\t\t\tvalidityPeriod: { firstDay: \"2026-11-01\", lastDay: \"\" },\n\t\t\t\t\t\trevisionId: \"\",\n\t\t\t\t\t\tsupersedesReleaseIds: [],\n\t\t\t\t\t\tproposed: false,\n\t\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\t\twithheld: false,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\t// The amendment's two saves, then the Revision Main holds.\n\t\t\trevisions: [\n\t\t\t\t{\n\t\t\t\t\tid: \"rev_p1_b1\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tparentId: \"rev_p1_a2\",\n\t\t\t\t\tsecondParentId: \"\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tcreateTime: \"2026-09-30T09:00:00.000Z\",\n\t\t\t\t\tauthor: STUB_USER_ID,\n\t\t\t\t\tcause: \"save\",\n\t\t\t\t\tbranchId: \"br_para_1_b\",\n\t\t\t\t\tchangeSetId: \"cs_bgbl_270\",\n\t\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit, Erbfähigkeit\" },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"rev_p1_a2\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tparentId: \"rev_p1_main\",\n\t\t\t\t\tsecondParentId: \"\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tcreateTime: \"2026-09-30T08:30:00.000Z\",\n\t\t\t\t\tauthor: STUB_OTHER_USER_ID,\n\t\t\t\t\tcause: \"save\",\n\t\t\t\t\tbranchId: \"br_para_1_a\",\n\t\t\t\t\tchangeSetId: \"cs_bgbl_270\",\n\t\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit des Menschen\" },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"rev_p1_main\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tparentId: \"\",\n\t\t\t\t\tsecondParentId: \"\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tcreateTime: at,\n\t\t\t\t\tauthor: STUB_USER_ID,\n\t\t\t\t\tcause: \"create\",\n\t\t\t\t\tbranchId: \"br_para_1_main\",\n\t\t\t\t\tchangeSetId: \"cs_correction_3\",\n\t\t\t\t},\n\t\t\t],\n\t\t\t// § 1 cites § 2 at a Release since superseded: an outdated pin.\n\t\t\tedges: [\n\t\t\t\t{\n\t\t\t\t\tsourceContentId: \"content_para_1\",\n\t\t\t\t\tsourceRevisionId: \"rev_p1_main\",\n\t\t\t\t\tpath: \"/see_also\",\n\t\t\t\t\tkind: \"reference\",\n\t\t\t\t\ttargetContentId: \"content_para_2\",\n\t\t\t\t\ttargetAssetId: \"\",\n\t\t\t\t\ttargetBlueprintReleaseId: \"\",\n\t\t\t\t\tpinReleaseId: \"rls_p2_0\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tid: \"content_para_2\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\tcollectionIds: [\"col_bgb\"],\n\t\t\tmain: {\n\t\t\t\trevisionId: \"rev_p2_main\",\n\t\t\t\tdata: { number: \"§ 2\", heading: \"Eintritt der Volljährigkeit\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tinForce: {\n\t\t\t\treleaseId: \"rls_p2_1\",\n\t\t\t\trevisionId: \"rev_p2_main\",\n\t\t\t\tdata: { number: \"§ 2\", heading: \"Eintritt der Volljährigkeit\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tbranches: {},\n\t\t\ttimeline: [\n\t\t\t\t{\n\t\t\t\t\tordinal: 1,\n\t\t\t\t\treleaseId: \"rls_p2_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\trevisionId: \"rev_p2_main\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"1975-01-01\", lastDay: \"\" },\n\t\t\t\t\tpublishTime: at,\n\t\t\t\t\tfirst: false,\n\t\t\t\t},\n\t\t\t],\n\t\t\t// § 2 refers to § 1 as it is In Force: § 1's referrer.\n\t\t\tedges: [\n\t\t\t\t{\n\t\t\t\t\tsourceContentId: \"content_para_2\",\n\t\t\t\t\tsourceRevisionId: \"rev_p2_main\",\n\t\t\t\t\tpath: \"/see_also\",\n\t\t\t\t\tkind: \"reference\",\n\t\t\t\t\ttargetContentId: \"content_para_1\",\n\t\t\t\t\ttargetAssetId: \"\",\n\t\t\t\t\ttargetBlueprintReleaseId: \"\",\n\t\t\t\t\tpinReleaseId: \"\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tid: \"content_para_4a\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tblueprintReleaseId: \"bpr_paragraph_2\",\n\t\t\tcollectionIds: [\"col_bgb\"],\n\t\t\tbranches: {\n\t\t\t\tcs_bgbl_270: {\n\t\t\t\t\tbranchId: \"br_para_4a\",\n\t\t\t\t\trevisionId: \"rev_p4a_1\",\n\t\t\t\t\tdata: { number: \"§ 4a\", heading: \"Elektronische Form\" },\n\t\t\t\t\trevisionCreateTime: \"2026-09-30T10:00:00.000Z\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: \"content_stgb_211\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\tcollectionIds: [\"col_stgb\"],\n\t\t\tassigneeIds: [STUB_OTHER_USER_ID],\n\t\t\tmain: {\n\t\t\t\trevisionId: \"rev_s211_main\",\n\t\t\t\tdata: { number: \"§ 211\", heading: \"Mord\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tinForce: {\n\t\t\t\treleaseId: \"rls_s211_1\",\n\t\t\t\trevisionId: \"rev_s211_main\",\n\t\t\t\tdata: { number: \"§ 211\", heading: \"Mord\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tbranches: {},\n\t\t\ttimeline: [\n\t\t\t\t{\n\t\t\t\t\tordinal: 1,\n\t\t\t\t\treleaseId: \"rls_s211_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\trevisionId: \"rev_s211_main\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"1941-09-15\", lastDay: \"\" },\n\t\t\t\t\tpublishTime: at,\n\t\t\t\t\tfirst: true,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t];\n}\n","// A `BlueprintSource` over fixed Blueprints and Releases, for a test that\n// overrides where the screens read Blueprints. Without one they read the\n// client's own catalog (#238), which the stub client serves too.\nimport type { BlueprintInfo, BlueprintReleaseInfo, BlueprintSource } from \"../types\";\nimport { stubBlueprintReleases, stubBlueprints } from \"./fixtures\";\n\nexport function createStubBlueprintSource(\n\tblueprints: BlueprintInfo[] = stubBlueprints(),\n\treleases: BlueprintReleaseInfo[] = stubBlueprintReleases(),\n): BlueprintSource {\n\treturn {\n\t\tasync searchBlueprints({ query }) {\n\t\t\tconst q = query.trim().toLocaleLowerCase();\n\t\t\treturn {\n\t\t\t\tblueprints: blueprints\n\t\t\t\t\t.filter((b) => b.name.toLocaleLowerCase().includes(q))\n\t\t\t\t\t.map((b) => ({ ...b })),\n\t\t\t\tnextPageToken: \"\",\n\t\t\t};\n\t\t},\n\t\tasync getBlueprints(ids) {\n\t\t\treturn blueprints.filter((b) => ids.includes(b.id)).map((b) => ({ ...b }));\n\t\t},\n\t\tasync listReleases(blueprintId) {\n\t\t\treturn releases.filter((r) => r.blueprintId === blueprintId).map((r) => ({ ...r }));\n\t\t},\n\t};\n}\n","// A `ContenthubClient` over an in-memory workspace seeded from the fixtures.\n//\n// It keeps state and applies the service's rules (internal/workspaceconfig,\n// internal/changesets), rather than answering every read with the same\n// fixture, so a screen's writes show up in its next read, and a refusal comes\n// back the way contenthub refuses it.\n//\n// Typed as the whole interface, so a method added to `ContenthubClient`\n// without an answer here fails this package's typecheck, not a host's test.\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport {\n\tAccessDeniedError,\n\tBLOCK_REASON_NAME_MAX,\n\tBLUEPRINT_ACCESSOR_MAX,\n\tBlockReasonNameTakenError,\n\tCHANGE_SET_NAME_MAX,\n\tCHECK_NOTE_MAX,\n\tChangeSetClosedError,\n\tCheckResultDeniedError,\n\tCOLLECTION_NAME_MAX,\n\tCONTENT_SEARCH_MAX,\n\tContentArchivedError,\n\tContentBlockedError,\n\ttype ContenthubClient,\n\tContentRefusedError,\n\tCoversReleaseError,\n\tDirectEditRefusedError,\n\tEditingModeRefusedError,\n\tGuardianModeRequiredError,\n\tInvalidInputError,\n\tMAX_BLUEPRINT_IDS,\n\tNameTakenError,\n\tPublishRefusedError,\n\tREQUIRED_CHECK_NAME_MAX,\n\tRestrictionUnavailableError,\n\tSOURCE_REFERENCE_MAX,\n\tStaleHeadError,\n\tStaleStatusError,\n\tStatusTransitionRefusedError,\n\tWithheldWorkError,\n} from \"../client/contenthub-client\";\nimport { headsOf, sameHeads } from \"../common/heads\";\nimport { DAY, inForceOnOrAfter, releaseInForceOn } from \"../common/in-force\";\nimport type {\n\tBlockReason,\n\tBlueprintInfo,\n\tBlueprintReleaseInfo,\n\tChangeSet,\n\tChangeSetStatusInfo,\n\tCheckResult,\n\tCheckStanding,\n\tCollection,\n\tCollectionGrant,\n\tContent,\n\tContentAttributes,\n\tContentView,\n\tEdge,\n\tEditingMode,\n\tEditingSettings,\n\tFieldChange,\n\tMergeField,\n\tPendingMerge,\n\tPendingMergeRef,\n\tPlannedEnd,\n\tPlannedRelease,\n\tPublishBlocker,\n\tReferrer,\n\tReferrerList,\n\tRelease,\n\tRequiredCheck,\n\tRequiredCheckInput,\n\tRequiredCheckRecorders,\n\tResolvedBlueprintRelease,\n\tResolvedField,\n\tRevision,\n\tTimelineEntry,\n} from \"../types\";\nimport {\n\tSTUB_NOW,\n\tSTUB_OTHER_USER_ID,\n\tSTUB_USER_ID,\n\ttype StubContent,\n\tstubBlockReasons,\n\tstubBlueprintReleases,\n\tstubBlueprints,\n\tstubChangeSetStatuses,\n\tstubChangeSets,\n\tstubCollections,\n\tstubContents,\n\tstubRequiredChecks,\n\tstubResolvedReleases,\n\tstubStatusTransitions,\n} from \"./fixtures\";\n\ntype SaveInput = Omit<Parameters<ContenthubClient[\"saveRevision\"]>[0], \"idempotencyKey\">;\n\nexport interface StubContenthubClientOptions {\n\t/** The workspace's Block Reasons to start from; the fixtures' by default. */\n\tblockReasons?: BlockReason[];\n\t/** The workspace's Change Sets to start from, newest first; the fixtures' by default. */\n\tchangeSets?: ChangeSet[];\n\t/**\n\t * statushub's `contenthub/change_set` catalogue the stub checks status\n\t * moves against; the fixtures' by default.\n\t */\n\tstatuses?: ChangeSetStatusInfo[];\n\t/** The moves statushub allows, from slug to slugs; the fixtures' by default. */\n\tstatusTransitions?: Record<string, string[]>;\n\t/** The workspace's Collections, by name; the fixtures' by default. */\n\tcollections?: Collection[];\n\t/** The workspace's Content, every way it can be read; the fixtures' by default. */\n\tcontents?: StubContent[];\n\t/**\n\t * The workspace's content Blueprints, as `getBlueprints` names them;\n\t * the fixtures' by default. `searchBlueprints` lists those Content can\n\t * be made from: not `archived`, with a Release.\n\t */\n\tblueprints?: (BlueprintInfo & { archived?: boolean })[];\n\t/**\n\t * The Blueprint Releases, newest first per Blueprint, as\n\t * `listBlueprintReleases` lists them; the fixtures' by default.\n\t * `createContent` pins one without `refusals` and refuses the rest, as\n\t * contenthub refuses a Release it can't load.\n\t */\n\tblueprintReleases?: (Pick<BlueprintReleaseInfo, \"id\" | \"blueprintId\"> &\n\t\tPartial<BlueprintReleaseInfo>)[];\n\t/** The Resolved Releases `getContent` answers with, by Blueprint Release id; the fixtures' by default. */\n\tresolvedReleases?: Record<string, ResolvedBlueprintRelease>;\n\t/**\n\t * The workspace's Required Checks; the fixtures' by default. The stub\n\t * reads `blueprintAccessors` as Blueprint ids, the one name its Content\n\t * carries.\n\t */\n\trequiredChecks?: RequiredCheck[];\n\t/** Check Results recorded before, in the order they were recorded. */\n\tcheckResults?: (CheckResult & { changeSetId: string })[];\n\t/**\n\t * Blockers the stub can't derive itself (versionkit's and the Content\n\t * Graph's, such as covers_release or dangling_pin), by Change Set id:\n\t * `validatePublish` and `publish` report them beside the ones it does\n\t * derive (moved_head, the dependencies', outstanding_check).\n\t */\n\tpublishBlockers?: Record<string, PublishBlocker[]>;\n\t/** The Pending Merges `updateFromMain` leaves, by Change Set id; none by default. */\n\tpendingMerges?: Record<string, PendingMergeRef[]>;\n\t/**\n\t * What an Update from Main would meet on a Branch, by Branch id: the\n\t * fields it can't merge and the rest merged. `updateFromMain` stores it\n\t * on the Branch as a Pending Merge; `pending` stores it from the start.\n\t */\n\tconflicts?: Record<string, StubConflict>;\n\t/**\n\t * contenthub's `authz.mode`: \"guardian\" by default. In \"workspace\" every\n\t * restriction and grant is refused, as contenthub refuses them, and\n\t * opening a Restricted Collection again is still allowed.\n\t */\n\tauthzMode?: \"workspace\" | \"guardian\";\n\t/** Grants on Restricted Collections, by Collection id, the owner's included. */\n\tcollectionGrants?: Record<string, CollectionGrant[]>;\n\t/**\n\t * The Change Sets, by id, holding work the caller can't see (Restricted\n\t * Content, ADR 0017): `validatePublish`, `publish`, `discardChangeSet`\n\t * and an `updateFromMain` without `chainId` refuse them with\n\t * `WithheldWorkError`, as contenthub does.\n\t */\n\twithheld?: string[];\n\t/**\n\t * Who records each Required Check, by check id; a check not named here,\n\t * and every new one, is recorded by every member. In guardian mode\n\t * `recordCheckResult` refuses a caller who is no recorder, as contenthub\n\t * does; in workspace mode every member records, and the recorder calls\n\t * are refused.\n\t */\n\trecorders?: Record<string, RequiredCheckRecorders>;\n\t/** The workspace's members, whom a grant may name; the stub identity's two by default. */\n\tmemberIds?: string[];\n\t/**\n\t * Whether the caller is a workspace admin, who manages every Restricted\n\t * Collection's grants; true by default. Otherwise only an owner does.\n\t */\n\tadmin?: boolean;\n\t/** Who the token names: the creator of a new Change Set. STUB_USER_ID by default. */\n\tuserId?: string;\n\t/** The time every write stamps; STUB_NOW by default. */\n\tnow?: () => string;\n\t/**\n\t * The workspace's own editing settings; \"Change Sets only\" without an\n\t * Editing Block by default, as for a workspace that never set them.\n\t */\n\teditingSettings?: EditingSettings;\n\t/** The per-Blueprint overrides of the editing settings; none by default. */\n\teditingOverrides?: StubEditingOverride[];\n}\n\n/** One stored override: a null field follows the workspace's. */\nexport interface StubEditingOverride {\n\tblueprintAccessor: string;\n\teditingMode: EditingMode | null;\n\teditingBlock: boolean | null;\n}\n\n/** A merge an Update from Main would stop on (see `conflicts`). */\nexport interface StubConflict {\n\ttheirsRevisionId: string;\n\tfields: MergeField[];\n\t/** Every field but `fields`, merged. */\n\tmerged: Record<string, unknown>;\n\treason?: \"conflict\" | \"invalid\";\n\t/** Already stored on the Branch, as an earlier Update from Main left it. */\n\tpending?: boolean;\n}\n\n/** The day after (1) or before (-1) a YYYY-MM-DD day. */\nfunction shiftDay(day: string, by: 1 | -1): string {\n\tconst d = new Date(`${day}T00:00:00Z`);\n\td.setUTCDate(d.getUTCDate() + by);\n\treturn d.toISOString().slice(0, 10);\n}\n\n/** The service's rule for a name: trimmed, not blank, at most `max` characters, one line. */\nfunction oneLine(raw: string, what: string, max: number): string {\n\tconst value = raw.trim();\n\tif (value === \"\") throw new InvalidInputError(`${what} is required`);\n\tif ([...value].length > max) {\n\t\tthrow new InvalidInputError(`${what} is at most ${max} characters`);\n\t}\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\tif (/[\\u0000-\\u001f\\u007f]/.test(value)) {\n\t\tthrow new InvalidInputError(`${what} is one line of text`);\n\t}\n\treturn value;\n}\n\n/** The service's rule for a Source: a YYYY-MM-DD day and a one-line reference. */\nfunction checkedSourceOf(source: { date: string; reference: string }): {\n\tdate: string;\n\treference: string;\n} {\n\tif (!/^\\d{4}-\\d{2}-\\d{2}$/.test(source.date.trim())) {\n\t\tthrow new InvalidInputError(`source.date \"${source.date}\" is not a day as YYYY-MM-DD`);\n\t}\n\treturn {\n\t\tdate: source.date.trim(),\n\t\treference: oneLine(source.reference, \"source.reference\", SOURCE_REFERENCE_MAX),\n\t};\n}\n\nfunction checkedBlockReasonName(raw: string): string {\n\tconst name = raw.trim();\n\tif (name === \"\") throw new InvalidInputError(\"a Block Reason needs a name\");\n\tif ([...name].length > BLOCK_REASON_NAME_MAX) {\n\t\tthrow new InvalidInputError(\n\t\t\t`a Block Reason's name is at most ${BLOCK_REASON_NAME_MAX} characters`,\n\t\t);\n\t}\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\tif (/[\\u0000-\\u001f\\u007f]/.test(name)) {\n\t\tthrow new InvalidInputError(\"a Block Reason's name is one line of text\");\n\t}\n\treturn name;\n}\n\n/** The service's rule for a Required Check (internal/workspaceconfig.checkRequiredCheck). */\nfunction checkedRequiredCheck(input: RequiredCheckInput): RequiredCheckInput {\n\tconst name = oneLine(input.name, \"a Required Check's name\", REQUIRED_CHECK_NAME_MAX);\n\tif (input.scope !== \"branch\" && input.scope !== \"change_set\") {\n\t\tthrow new InvalidInputError(\"a Required Check's scope is Branch or Change Set\");\n\t}\n\tconst accessors = input.blueprintAccessors.map((raw) => {\n\t\tconst a = raw.trim();\n\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\t\tif (a === \"\" || [...a].length > BLUEPRINT_ACCESSOR_MAX || /[\\u0000-\\u001f\\u007f]/.test(a)) {\n\t\t\tthrow new InvalidInputError(`\"${a}\" is not a Blueprint accessor`);\n\t\t}\n\t\treturn a;\n\t});\n\treturn {\n\t\tname,\n\t\tscope: input.scope,\n\t\tblueprintAccessors: [...new Set(accessors)].sort(),\n\t\tindependent: input.independent,\n\t};\n}\n\n/** What contenthub answers to every recorder call in `authz.mode: workspace`. */\nconst RECORDERS_WORKSPACE_MODE =\n\t\"who records a Required Check can be narrowed only in authz.mode guardian: \" +\n\t\"in workspace mode every member records every check (ADR 0017)\";\n\n/** What contenthub answers to every whole-Change-Set write over withheld work. */\nconst WITHHELD_REFUSAL =\n\t\"this Change Set holds work you can't see: publishing, discarding or updating all of it \" +\n\t\"needs you to see every Content in it\";\n\n/** What contenthub answers to every restriction in `authz.mode: workspace`. */\nconst WORKSPACE_MODE_REFUSAL =\n\t\"Restricted Collections need authz.mode guardian: in workspace mode a restriction \" +\n\t\"could not be enforced (ADR 0017)\";\n\nfunction notFound(what: string, id: string): ConnectError {\n\treturn new ConnectError(`${what} ${id}: not found`, Code.NotFound);\n}\n\nconst copy = (cs: ChangeSet): ChangeSet => structuredClone(cs);\n\n/** A blocker naming only what `fields` sets; every other id \"\", as on the wire. */\nexport function stubBlocker(code: string, fields: Partial<PublishBlocker> = {}): PublishBlocker {\n\treturn {\n\t\tcode,\n\t\tcontentId: \"\",\n\t\tbranchId: \"\",\n\t\texpectedHeadId: \"\",\n\t\tcurrentHeadId: \"\",\n\t\treleaseId: \"\",\n\t\toverlapsReleaseId: \"\",\n\t\tdependencyChangeSetId: \"\",\n\t\tpath: \"\",\n\t\ttargetContentId: \"\",\n\t\tassetId: \"\",\n\t\tparentContentIds: [],\n\t\trequiredCheckId: \"\",\n\t\tcoveredReleaseId: \"\",\n\t\trevisionId: \"\",\n\t\t...fields,\n\t};\n}\n\nexport function createStubContenthubClient(\n\toptions: StubContenthubClientOptions = {},\n): ContenthubClient {\n\tconst now = options.now ?? (() => STUB_NOW);\n\tconst userId = options.userId ?? STUB_USER_ID;\n\tconst statuses = options.statuses ?? stubChangeSetStatuses();\n\tconst transitions = options.statusTransitions ?? stubStatusTransitions();\n\tlet reasons = (options.blockReasons ?? stubBlockReasons()).map((r) => ({ ...r }));\n\t// Newest first, the order the service lists them in.\n\tconst changeSets = (options.changeSets ?? stubChangeSets()).map(copy);\n\tconst collections = (options.collections ?? stubCollections()).map((c) => ({ ...c }));\n\tconst contents = structuredClone(options.contents ?? stubContents());\n\tconst blueprints: (BlueprintInfo & { archived?: boolean })[] =\n\t\toptions.blueprints ?? stubBlueprints();\n\tconst releases = options.blueprintReleases ?? stubBlueprintReleases();\n\tconst resolved = options.resolvedReleases ?? stubResolvedReleases();\n\tlet requiredChecks = structuredClone(options.requiredChecks ?? stubRequiredChecks());\n\tconst authzMode = options.authzMode ?? \"guardian\";\n\tconst withheld = new Set(options.withheld ?? []);\n\t/** Refuses a write over all of Change Set `id` while it holds work the caller can't see. */\n\tconst refuseWithheld = (id: string) => {\n\t\tif (withheld.has(id)) throw new WithheldWorkError(WITHHELD_REFUSAL);\n\t};\n\tconst grants = new Map<string, CollectionGrant[]>(\n\t\tObject.entries(structuredClone(options.collectionGrants ?? {})),\n\t);\n\tconst recorders = new Map<string, RequiredCheckRecorders>(\n\t\tObject.entries(structuredClone(options.recorders ?? {})),\n\t);\n\tconst recordersOf = (checkId: string): RequiredCheckRecorders =>\n\t\trecorders.get(checkId) ?? { everyMember: true, userIds: [] };\n\tconst memberIds = options.memberIds ?? [STUB_USER_ID, STUB_OTHER_USER_ID];\n\tconst admin = options.admin ?? true;\n\tlet workspaceEditing: EditingSettings = structuredClone(\n\t\toptions.editingSettings ?? { editingMode: \"change_sets\", editingBlock: false },\n\t);\n\tlet editingOverrides = structuredClone(options.editingOverrides ?? []);\n\t/** An override over the workspace's settings, field by field (internal/workspaceconfig). */\n\tconst effectiveOf = (o: StubEditingOverride | undefined): EditingSettings => ({\n\t\teditingMode: o?.editingMode ?? workspaceEditing.editingMode,\n\t\teditingBlock: o?.editingBlock ?? workspaceEditing.editingBlock,\n\t});\n\tconst overrideOut = (o: StubEditingOverride) => ({\n\t\t...structuredClone(o),\n\t\teffective: effectiveOf(o),\n\t});\n\tconst editingModes: EditingMode[] = [\"direct_edits\", \"change_sets\", \"both\"];\n\tconst adminOnly = () => {\n\t\tif (!admin) throw new AccessDeniedError(\"permission denied\");\n\t};\n\tconst checkResults = structuredClone(options.checkResults ?? []);\n\tconst extraBlockers = options.publishBlockers ?? {};\n\tconst pendingMerges = options.pendingMerges ?? {};\n\tconst conflicts = structuredClone(options.conflicts ?? {});\n\t// The Pending Merges stored on Branches, by Branch id.\n\tconst stored = new Map<string, PendingMerge>();\n\t// What each Idempotency Key's write asked and answered, beside the saves'.\n\tconst wroteUnder = new Map<string, { asked: string; answer: unknown }>();\n\t/**\n\t * A write under an Idempotency Key: a repeat answers the first and\n\t * writes nothing, another request under the key is refused.\n\t */\n\tconst once = async <T>(key: string | undefined, request: unknown, write: () => Promise<T>) => {\n\t\tif (!key) return write();\n\t\tconst asked = JSON.stringify(request);\n\t\tconst kept = wroteUnder.get(key);\n\t\tif (kept) {\n\t\t\tif (kept.asked !== asked) {\n\t\t\t\tthrow new InvalidInputError(`idempotency key ${key} names another request`);\n\t\t\t}\n\t\t\treturn structuredClone(kept.answer) as T;\n\t\t}\n\t\tconst answer = await write();\n\t\twroteUnder.set(key, { asked, answer: structuredClone(answer) });\n\t\treturn answer;\n\t};\n\t// The heads each published Change Set was published with, for a repeat.\n\tconst publishedWith = new Map<string, Record<string, string>>();\n\t// What each Idempotency Key's save asked and answered.\n\tconst savedUnder = new Map<string, { asked: string; content: Content }>();\n\tlet next = 1;\n\n\tconst findContent = (id: string): StubContent => {\n\t\tconst c = contents.find((each) => each.id === id);\n\t\tif (!c) throw notFound(\"Content\", id);\n\t\treturn c;\n\t};\n\tconst attributesOf = (c: StubContent): ContentAttributes =>\n\t\tstructuredClone({\n\t\t\tcollectionIds: [...c.collectionIds].sort(),\n\t\t\tassigneeIds: c.assigneeIds ?? [],\n\t\t\tblock: c.block,\n\t\t\tarchiveTime: c.archiveTime,\n\t\t});\n\tconst today = () => now().slice(0, 10);\n\tconst datedContent = (c: StubContent) => resolved[c.blueprintReleaseId]?.dated ?? false;\n\t// Every Revision the stub knows of a Content, newest first, with its data\n\t// where known: those the fixture lists, then each head not among them.\n\tconst revisionsOf = (c: StubContent): (Revision & { data?: Record<string, unknown> })[] => {\n\t\tconst listed = [...(c.revisions ?? [])];\n\t\tconst heads = [\n\t\t\t...Object.entries(c.branches).map(([csId, h]) => ({ ...h, changeSetId: csId })),\n\t\t\t...(c.main ? [{ ...c.main, branchId: \"\", changeSetId: \"\" }] : []),\n\t\t];\n\t\tfor (const h of heads) {\n\t\t\tif (listed.some((r) => r.id === h.revisionId)) continue;\n\t\t\tlisted.push({\n\t\t\t\tid: h.revisionId,\n\t\t\t\tcontentId: c.id,\n\t\t\t\tparentId: \"\",\n\t\t\t\tsecondParentId: \"\",\n\t\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\t\tcreateTime: h.revisionCreateTime,\n\t\t\t\tauthor: userId,\n\t\t\t\tcause: \"create\",\n\t\t\t\tbranchId: h.branchId,\n\t\t\t\tchangeSetId: h.changeSetId,\n\t\t\t\tdata: h.data,\n\t\t\t});\n\t\t}\n\t\treturn listed.sort((a, b) =>\n\t\t\ta.createTime < b.createTime ? 1 : a.createTime > b.createTime ? -1 : 0,\n\t\t);\n\t};\n\tconst dataOf = (c: StubContent, revisionId: string): Record<string, unknown> | undefined => {\n\t\tconst heads = [c.main, c.inForce, ...Object.values(c.branches)];\n\t\treturn (\n\t\t\theads.find((h) => h?.revisionId === revisionId)?.data ??\n\t\t\tc.revisions?.find((r) => r.id === revisionId)?.data\n\t\t);\n\t};\n\t/**\n\t * fieldkit's `required`, the one rule of its data contract the stub\n\t * applies: the accessors of the top-level required fields `values`\n\t * leaves Unset.\n\t */\n\tconst missingRequired = (\n\t\tfields: ResolvedField[] | undefined,\n\t\tvalues: Record<string, unknown>,\n\t): string[] => {\n\t\tconst unset = (v: unknown) =>\n\t\t\tv === undefined || v === null || v === \"\" || (Array.isArray(v) && v.length === 0);\n\t\treturn (fields ?? [])\n\t\t\t.filter((f) => f.config.required === true && unset(values[f.config.api_accessor]))\n\t\t\t.map((f) => f.config.api_accessor);\n\t};\n\tconst checkEditable = (c: StubContent) => {\n\t\tif (c.archiveTime) throw new ContentArchivedError(c.id);\n\t\tif (c.block && !c.block.allowedUserIds.includes(userId)) {\n\t\t\tthrow new ContentBlockedError(c.id, c.block.blockReasonId);\n\t\t}\n\t};\n\t/** The unpinned edges of Releases In Force pointing at `contentId`: what a Repeal leaves with a gap. */\n\tconst gapReferrersOf = (contentId: string): PlannedEnd[\"gapReferrers\"] =>\n\t\tcontents.flatMap((other) =>\n\t\t\t(other.edges ?? [])\n\t\t\t\t.filter(\n\t\t\t\t\t(e) =>\n\t\t\t\t\t\te.targetContentId === contentId &&\n\t\t\t\t\t\te.pinReleaseId === \"\" &&\n\t\t\t\t\t\tother.inForce?.revisionId === e.sourceRevisionId,\n\t\t\t\t)\n\t\t\t\t.map((e) => ({ edge: { ...e }, releaseId: other.inForce?.releaseId ?? \"\" })),\n\t\t);\n\n\t// The service orders by name, then id, compared as bytes.\n\tconst byName = (a: BlockReason, b: BlockReason) =>\n\t\ta.name < b.name ? -1 : a.name > b.name ? 1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\tconst taken = (name: string, except?: string) =>\n\t\treasons.some((r) => r.name === name && r.id !== except);\n\n\t// The service orders Collections by name, then id, compared as bytes.\n\tconst collectionOrder = (a: Collection, b: Collection) =>\n\t\ta.name < b.name ? -1 : a.name > b.name ? 1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\tconst findCollection = (id: string): Collection => {\n\t\tconst c = collections.find((each) => each.id === id);\n\t\tif (!c) throw notFound(\"Collection\", id);\n\t\treturn c;\n\t};\n\tconst siblingNamed = (parentId: string, name: string, except?: string) =>\n\t\tcollections.some((c) => c.parentId === parentId && c.name === name && c.id !== except);\n\t/** Refuses grant management the caller may not do, as the service does. */\n\tconst manageable = (id: string) => {\n\t\tif (authzMode === \"workspace\") throw new RestrictionUnavailableError(WORKSPACE_MODE_REFUSAL);\n\t\tconst c = findCollection(id);\n\t\tif (!c.restricted) {\n\t\t\tthrow new InvalidInputError(\n\t\t\t\t`Collection ${id} is open: only a Restricted Collection takes grants`,\n\t\t\t);\n\t\t}\n\t\tconst owns = (grants.get(id) ?? []).some((g) => g.userId === userId && g.level === \"owner\");\n\t\tif (!admin && !owns) {\n\t\t\tthrow new AccessDeniedError(\"only its owner or a workspace admin manages its grants\");\n\t\t}\n\t};\n\n\t/** Refuses recorder management the service would refuse, and returns the check's recorders. */\n\tconst narrowable = (checkId: string): RequiredCheckRecorders => {\n\t\tif (authzMode === \"workspace\") {\n\t\t\tthrow new GuardianModeRequiredError(\"required_check_recorders\", RECORDERS_WORKSPACE_MODE);\n\t\t}\n\t\tif (!admin) throw new AccessDeniedError(\"permission denied\");\n\t\tif (checkId === \"\") throw new InvalidInputError(\"required_check_id is required\");\n\t\tif (!requiredChecks.some((c) => c.id === checkId)) throw notFound(\"Required Check\", checkId);\n\t\treturn recordersOf(checkId);\n\t};\n\n\t/** One save, as SaveRevision applies it without an Idempotency Key. */\n\tconst saveOnce = async ({\n\t\tchangeSetId,\n\t\tbranchId,\n\t\texpectedHeadId,\n\t\tdata,\n\t\tfieldMask,\n\t}: SaveInput): Promise<Content> => {\n\t\tconst cs = open(changeSetId);\n\t\tconst chain = cs.chains.find((ch) => ch.branches.some((b) => b.id === branchId));\n\t\tconst branch = chain?.branches.find((b) => b.id === branchId);\n\t\tif (!chain || !branch) throw notFound(\"Branch\", branchId);\n\t\tconst c = findContent(chain.contentId);\n\t\tcheckEditable(c);\n\t\tif (stored.has(branchId)) {\n\t\t\tthrow new InvalidInputError(\n\t\t\t\t\"a Pending Merge waits on this Branch: resolve or abort it first\",\n\t\t\t);\n\t\t}\n\t\tif (expectedHeadId === \"\") throw new InvalidInputError(\"expected_head_id is required\");\n\t\tif (branch.headRevisionId !== expectedHeadId) {\n\t\t\tthrow new StaleHeadError({\n\t\t\t\tcontentId: c.id,\n\t\t\t\tbranchId,\n\t\t\t\texpectedHeadId,\n\t\t\t\tcurrentHeadId: branch.headRevisionId,\n\t\t\t});\n\t\t}\n\t\tconst head = dataOf(c, branch.headRevisionId) ?? {};\n\t\t// Through JSON, as the wire carries it: no `undefined` survives.\n\t\tconst sent = JSON.parse(JSON.stringify(data)) as Record<string, unknown>;\n\t\tlet saved: Record<string, unknown>;\n\t\tif (fieldMask) {\n\t\t\tconst stray = Object.keys(sent).filter((k) => !fieldMask.includes(k));\n\t\t\tif (stray.length > 0) {\n\t\t\t\tthrow new InvalidInputError(`data holds ${stray.join(\", \")}, which the mask doesn't name`);\n\t\t\t}\n\t\t\tsaved = structuredClone(head);\n\t\t\tfor (const key of fieldMask) {\n\t\t\t\tif (key in sent) saved[key] = sent[key];\n\t\t\t\telse delete saved[key];\n\t\t\t}\n\t\t} else {\n\t\t\tsaved = sent;\n\t\t}\n\t\t// No rule of fieldkit's data contract is applied: a save may leave\n\t\t// required Fields empty, and Publish asks for them (#180).\n\t\treturn writeHead({ changeSetId, chain, branch, c, data: saved, cause: \"save\" });\n\t};\n\n\t/** Writes a Revision on a Branch, on its head, which it becomes. */\n\tconst writeHead = ({\n\t\tchangeSetId,\n\t\tchain,\n\t\tbranch,\n\t\tc,\n\t\tdata,\n\t\tcause,\n\t\tsecondParentId = \"\",\n\t}: {\n\t\tchangeSetId: string;\n\t\tchain: ChangeSet[\"chains\"][number];\n\t\tbranch: ChangeSet[\"chains\"][number][\"branches\"][number];\n\t\tc: StubContent;\n\t\tdata: Record<string, unknown>;\n\t\tcause: Revision[\"cause\"];\n\t\tsecondParentId?: string;\n\t}): Content => {\n\t\tconst branchId = branch.id;\n\t\tconst n = next++;\n\t\tconst revisionId = `rev_stub_${n}`;\n\t\tconst createTime = now();\n\t\tc.revisions = [\n\t\t\t{\n\t\t\t\tid: revisionId,\n\t\t\t\tcontentId: c.id,\n\t\t\t\tparentId: branch.headRevisionId,\n\t\t\t\tsecondParentId,\n\t\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\t\tcreateTime,\n\t\t\t\tauthor: userId,\n\t\t\t\tcause,\n\t\t\t\tbranchId,\n\t\t\t\tchangeSetId,\n\t\t\t\tdata: structuredClone(data),\n\t\t\t},\n\t\t\t...(c.revisions ?? []),\n\t\t];\n\t\tbranch.headRevisionId = revisionId;\n\t\t// The Change Set read holds the head of the Chain's last Branch.\n\t\tif (chain.branches.at(-1)?.id === branchId) {\n\t\t\tc.branches[changeSetId] = {\n\t\t\t\tbranchId,\n\t\t\t\trevisionId,\n\t\t\t\tdata: structuredClone(data),\n\t\t\t\trevisionCreateTime: createTime,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tid: c.id,\n\t\t\tblueprintId: c.blueprintId,\n\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\trevisionId,\n\t\t\tdata: structuredClone(data),\n\t\t\tchangeSetId,\n\t\t\tbranchId,\n\t\t\trevisionCreateTime: createTime,\n\t\t\treleaseId: \"\",\n\t\t};\n\t};\n\n\t/** The Chain and Branch of `branchId` in an open Change Set, and its Content. */\n\tconst branchIn = (changeSetId: string, branchId: string) => {\n\t\tconst cs = open(changeSetId);\n\t\tconst chain = cs.chains.find((ch) => ch.branches.some((b) => b.id === branchId));\n\t\tconst branch = chain?.branches.find((b) => b.id === branchId);\n\t\tif (!chain || !branch) throw notFound(\"Branch\", branchId);\n\t\treturn { cs, chain, branch, c: findContent(chain.contentId) };\n\t};\n\n\t/** Stores what an Update from Main met on a Branch as its Pending Merge. */\n\tconst storeMerge = (branchId: string, conflict: StubConflict) => {\n\t\tfor (const cs of changeSets) {\n\t\t\tfor (const chain of cs.chains) {\n\t\t\t\tconst branch = chain.branches.find((b) => b.id === branchId);\n\t\t\t\tif (!branch) continue;\n\t\t\t\tconst pm: PendingMerge = {\n\t\t\t\t\tbranchId,\n\t\t\t\t\tcontentId: chain.contentId,\n\t\t\t\t\treason: conflict.reason ?? \"conflict\",\n\t\t\t\t\toursRevisionId: branch.headRevisionId,\n\t\t\t\t\ttheirsRevisionId: conflict.theirsRevisionId,\n\t\t\t\t\tcarried: false,\n\t\t\t\t\tfields: structuredClone(conflict.fields),\n\t\t\t\t\tmerged: structuredClone(conflict.merged),\n\t\t\t\t};\n\t\t\t\tstored.set(branchId, pm);\n\t\t\t\tbranch.hasPendingMerge = true;\n\t\t\t\tdelete conflicts[branchId];\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthrow notFound(\"Branch\", branchId);\n\t};\n\tconst dropMerge = (branchId: string) => {\n\t\tstored.delete(branchId);\n\t\tfor (const cs of changeSets) {\n\t\t\tfor (const chain of cs.chains) {\n\t\t\t\tconst branch = chain.branches.find((b) => b.id === branchId);\n\t\t\t\tif (branch) branch.hasPendingMerge = false;\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * A plan checked as the service checks it: a Validity Period for Dated\n\t * Content and none for undated, its Release Spec's required values, and\n\t * no Release of the Content covered entirely unless it supersedes it.\n\t */\n\tconst checkPlan = (\n\t\tc: StubContent,\n\t\tplan: Pick<PlannedRelease, \"validityPeriod\" | \"releaseSpec\" | \"supersedesReleaseIds\">,\n\t) => {\n\t\tconst vp = plan.validityPeriod;\n\t\tif (datedContent(c)) {\n\t\t\tif (!vp || !DAY.test(vp.firstDay)) {\n\t\t\t\tthrow new InvalidInputError(\"validity_period.first_day is required for Dated Content\");\n\t\t\t}\n\t\t\tif (vp.lastDay !== \"\" && (!DAY.test(vp.lastDay) || vp.lastDay < vp.firstDay)) {\n\t\t\t\tthrow new InvalidInputError(\"validity_period.last_day is a day on or after first_day\");\n\t\t\t}\n\t\t} else if (vp) {\n\t\t\tthrow new InvalidInputError(\"validity_period is refused for undated Content\");\n\t\t}\n\t\tconst violations = missingRequired(\n\t\t\tresolved[c.blueprintReleaseId]?.releaseSpec,\n\t\t\tplan.releaseSpec ?? {},\n\t\t).map((accessor) => ({ source: \"fieldkit\", code: \"required\", path: `/${accessor}` }));\n\t\tif (violations.length > 0) {\n\t\t\tthrow new ContentRefusedError(\n\t\t\t\t\"the Release Spec values break the Blueprint Release\",\n\t\t\t\tviolations,\n\t\t\t);\n\t\t}\n\t\tif (vp && vp.lastDay !== \"\") {\n\t\t\tconst covered = (c.timeline ?? [])\n\t\t\t\t.filter(\n\t\t\t\t\t(e) =>\n\t\t\t\t\t\te.validityPeriod &&\n\t\t\t\t\t\te.validityPeriod.lastDay !== \"\" &&\n\t\t\t\t\t\tvp.firstDay <= e.validityPeriod.firstDay &&\n\t\t\t\t\t\te.validityPeriod.lastDay <= vp.lastDay &&\n\t\t\t\t\t\t!plan.supersedesReleaseIds.includes(e.releaseId),\n\t\t\t\t)\n\t\t\t\t.map((e) => e.releaseId);\n\t\t\tif (covered.length > 0) throw new CoversReleaseError(c.id, covered);\n\t\t}\n\t};\n\n\t/**\n\t * The Change Set's proposals for a Content, derived again from its plans\n\t * (versionkit ADR 0003): a date-only cut of each Release a planned period\n\t * cuts into, and a tail resuming its wording after a period strictly\n\t * inside it. A proposal keeps its id while it proposes for the same Release.\n\t */\n\tconst repropose = (cs: ChangeSet, c: StubContent) => {\n\t\tconst previous = cs.plannedReleases.filter((p) => p.contentId === c.id && p.proposed);\n\t\tconst kept = cs.plannedReleases.filter((p) => !(p.contentId === c.id && p.proposed));\n\t\tconst proposals: PlannedRelease[] = [];\n\t\tconst propose = (\n\t\t\te: TimelineEntry,\n\t\t\tvalidityPeriod: { firstDay: string; lastDay: string },\n\t\t\tsplitFromReleaseId: string,\n\t\t) => {\n\t\t\tconst same = previous.find(\n\t\t\t\t(p) =>\n\t\t\t\t\tp.proposedForReleaseId === e.releaseId && p.splitFromReleaseId === splitFromReleaseId,\n\t\t\t);\n\t\t\tproposals.push({\n\t\t\t\tid: same?.id ?? `rls_stub_${next++}`,\n\t\t\t\tcontentId: c.id,\n\t\t\t\tkind: \"date_only\",\n\t\t\t\tbranchId: \"\",\n\t\t\t\trevisionId: e.revisionId,\n\t\t\t\tvalidityPeriod,\n\t\t\t\tsupersedesReleaseIds: splitFromReleaseId ? [] : [e.releaseId],\n\t\t\t\tproposed: true,\n\t\t\t\tproposedForReleaseId: e.releaseId,\n\t\t\t\tsplitFromReleaseId,\n\t\t\t\twithheld: false,\n\t\t\t});\n\t\t};\n\t\tfor (const plan of kept) {\n\t\t\tconst vp = plan.validityPeriod;\n\t\t\tif (plan.contentId !== c.id || plan.kind !== \"revision\" || !vp) continue;\n\t\t\tfor (const e of c.timeline ?? []) {\n\t\t\t\tconst its = e.validityPeriod;\n\t\t\t\tif (!its || plan.supersedesReleaseIds.includes(e.releaseId)) continue;\n\t\t\t\tif (!(its.firstDay < vp.firstDay && (its.lastDay === \"\" || its.lastDay >= vp.firstDay))) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpropose(e, { firstDay: its.firstDay, lastDay: shiftDay(vp.firstDay, -1) }, \"\");\n\t\t\t\tif (vp.lastDay !== \"\" && (its.lastDay === \"\" || its.lastDay > vp.lastDay)) {\n\t\t\t\t\tpropose(e, { firstDay: shiftDay(vp.lastDay, 1), lastDay: its.lastDay }, e.releaseId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcs.plannedReleases = [...kept, ...proposals];\n\t};\n\n\tconst find = (id: string): ChangeSet => {\n\t\tconst cs = changeSets.find((c) => c.id === id);\n\t\tif (!cs) throw notFound(\"Change Set\", id);\n\t\treturn cs;\n\t};\n\tconst open = (id: string): ChangeSet => {\n\t\tconst cs = find(id);\n\t\tif (cs.state !== \"open\") throw new ChangeSetClosedError(cs.state);\n\t\treturn cs;\n\t};\n\tconst statusName = (slug: string) => statuses.find((s) => s.slug === slug)?.name ?? slug;\n\t// Whether `from` reaches `to` through dependencies.\n\tconst reaches = (from: string, to: string, seen = new Set<string>()): boolean => {\n\t\tif (from === to) return true;\n\t\tif (seen.has(from)) return false;\n\t\tseen.add(from);\n\t\tconst cs = changeSets.find((c) => c.id === from);\n\t\treturn (cs?.dependsOnChangeSetIds ?? []).some((d) => reaches(d, to, seen));\n\t};\n\n\t// What a Required Check applies to in a Change Set, as the service's\n\t// currentView reads it: every Branch at its head, then every Branch-less\n\t// Planned Release at the Revision it re-pins.\n\tconst subjectsOf = (cs: ChangeSet) => [\n\t\t...cs.chains.flatMap((chain) =>\n\t\t\tchain.branches.map((b) => ({\n\t\t\t\tkey: b.id,\n\t\t\t\tbranchless: false,\n\t\t\t\tcontentId: chain.contentId,\n\t\t\t\trevision: b.headRevisionId,\n\t\t\t})),\n\t\t),\n\t\t...cs.plannedReleases\n\t\t\t.filter((pr) => pr.kind !== \"revision\" && pr.revisionId !== \"\")\n\t\t\t.map((pr) => ({\n\t\t\t\tkey: pr.id,\n\t\t\t\tbranchless: true,\n\t\t\t\tcontentId: pr.contentId,\n\t\t\t\trevision: pr.revisionId,\n\t\t\t})),\n\t];\n\tconst blueprintOf = (contentId: string) => contents.find((c) => c.id === contentId)?.blueprintId;\n\tconst covers = (check: RequiredCheck, contentId: string) =>\n\t\tcheck.blueprintAccessors.length === 0 ||\n\t\tcheck.blueprintAccessors.includes(blueprintOf(contentId) ?? \"\");\n\n\t/** Where each check stands, by name, as ListCheckResults answers. */\n\tconst standingsOf = (cs: ChangeSet): CheckStanding[] => {\n\t\tconst subjects = subjectsOf(cs);\n\t\t// Newest first. A Branch-scope result is about the one head it names,\n\t\t// a Change Set-scope one (\"\" here) about the whole.\n\t\tconst resultsOn = (check: RequiredCheck, subject: string): CheckResult[] =>\n\t\t\tcheckResults\n\t\t\t\t.filter((r) => r.changeSetId === cs.id && r.requiredCheckId === check.id)\n\t\t\t\t.filter((r) => (check.scope === \"change_set\" ? \"\" : Object.keys(r.heads)[0]) === subject)\n\t\t\t\t.reverse()\n\t\t\t\t.map(({ changeSetId: _, ...r }) => structuredClone(r));\n\t\tconst standing = (\n\t\t\tcheck: RequiredCheck,\n\t\t\tat: Pick<CheckStanding, \"contentId\" | \"branchId\" | \"releaseId\" | \"heads\">,\n\t\t\tresults: CheckResult[],\n\t\t): CheckStanding => {\n\t\t\tconst latest = results[0];\n\t\t\tconst stale = latest ? !sameHeads(latest.heads, at.heads) : false;\n\t\t\treturn {\n\t\t\t\tcheck: structuredClone(check),\n\t\t\t\t...at,\n\t\t\t\tresults,\n\t\t\t\tstale,\n\t\t\t\tcleared: !!latest && !stale && latest.outcome !== \"failed\",\n\t\t\t};\n\t\t};\n\t\tconst out: CheckStanding[] = [];\n\t\t// By name, then id, as the service orders them.\n\t\tconst byNameThenId = (a: RequiredCheck, b: RequiredCheck) =>\n\t\t\ta.name < b.name ? -1 : a.name > b.name ? 1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\t\tfor (const check of [...requiredChecks].sort(byNameThenId)) {\n\t\t\tconst covered = subjects.filter((s) => covers(check, s.contentId));\n\t\t\tif (check.scope === \"change_set\") {\n\t\t\t\tif (covered.length === 0) continue;\n\t\t\t\tconst heads = Object.fromEntries(subjects.map((s) => [s.key, s.revision]));\n\t\t\t\tout.push(\n\t\t\t\t\tstanding(\n\t\t\t\t\t\tcheck,\n\t\t\t\t\t\t{ contentId: \"\", branchId: \"\", releaseId: \"\", heads },\n\t\t\t\t\t\tresultsOn(check, \"\"),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const s of covered) {\n\t\t\t\tout.push(\n\t\t\t\t\tstanding(\n\t\t\t\t\t\tcheck,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontentId: s.contentId,\n\t\t\t\t\t\t\tbranchId: s.branchless ? \"\" : s.key,\n\t\t\t\t\t\t\treleaseId: s.branchless ? s.key : \"\",\n\t\t\t\t\t\t\theads: { [s.key]: s.revision },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresultsOn(check, s.key),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t};\n\n\t/**\n\t * The blockers a Publish of `cs` with `reviewed` meets: moved heads, open\n\t * or discarded dependencies, outstanding checks, top-level required\n\t * Fields a Branch head leaves empty, and what the options add for the\n\t * rest.\n\t */\n\tconst blockersOf = (cs: ChangeSet, reviewed: Record<string, string>): PublishBlocker[] => {\n\t\tconst out: PublishBlocker[] = [];\n\t\tconst current = headsOf(cs);\n\t\tfor (const chain of cs.chains) {\n\t\t\tfor (const b of chain.branches) {\n\t\t\t\tif (reviewed[b.id] !== b.headRevisionId) {\n\t\t\t\t\tout.push(\n\t\t\t\t\t\tstubBlocker(\"moved_head\", {\n\t\t\t\t\t\t\tcontentId: chain.contentId,\n\t\t\t\t\t\t\tbranchId: b.id,\n\t\t\t\t\t\t\texpectedHeadId: reviewed[b.id] ?? \"\",\n\t\t\t\t\t\t\tcurrentHeadId: b.headRevisionId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const [id, head] of Object.entries(reviewed)) {\n\t\t\tif (!(id in current)) {\n\t\t\t\tout.push(stubBlocker(\"moved_head\", { branchId: id, expectedHeadId: head }));\n\t\t\t}\n\t\t}\n\t\tfor (const dep of cs.dependsOnChangeSetIds) {\n\t\t\tconst state = changeSets.find((c) => c.id === dep)?.state;\n\t\t\tif (state === \"open\") {\n\t\t\t\tout.push(stubBlocker(\"unpublished_dependency\", { dependencyChangeSetId: dep }));\n\t\t\t} else if (state === \"discarded\") {\n\t\t\t\tout.push(stubBlocker(\"discarded_dependency\", { dependencyChangeSetId: dep }));\n\t\t\t}\n\t\t}\n\t\tfor (const st of standingsOf(cs)) {\n\t\t\tif (!st.cleared) {\n\t\t\t\tout.push(\n\t\t\t\t\tstubBlocker(\"outstanding_check\", {\n\t\t\t\t\t\trequiredCheckId: st.check.id,\n\t\t\t\t\t\tcontentId: st.contentId,\n\t\t\t\t\t\tbranchId: st.branchId,\n\t\t\t\t\t\treleaseId: st.releaseId,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tfor (const chain of cs.chains) {\n\t\t\tconst c = contents.find((x) => x.id === chain.contentId);\n\t\t\tfor (const b of chain.branches) {\n\t\t\t\tconst data = c && dataOf(c, b.headRevisionId);\n\t\t\t\tif (!c || !data) continue;\n\t\t\t\tfor (const accessor of missingRequired(resolved[c.blueprintReleaseId]?.fields, data)) {\n\t\t\t\t\tout.push(\n\t\t\t\t\t\tstubBlocker(\"missing_required_field\", {\n\t\t\t\t\t\t\tcontentId: c.id,\n\t\t\t\t\t\t\trevisionId: b.headRevisionId,\n\t\t\t\t\t\t\tpath: `/${accessor}`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn [...out, ...structuredClone(extraBlockers[cs.id] ?? [])];\n\t};\n\n\t/** The Releases a Publish of `cs` cuts: every Planned Release not withheld. */\n\tconst releasesOf = (cs: ChangeSet): Release[] => {\n\t\tconst current = headsOf(cs);\n\t\treturn cs.plannedReleases\n\t\t\t.filter((pr) => !pr.withheld)\n\t\t\t.map((pr) => ({\n\t\t\t\tid: pr.id,\n\t\t\t\tcontentId: pr.contentId,\n\t\t\t\tkind: pr.kind,\n\t\t\t\tbranchId: pr.branchId,\n\t\t\t\trevisionId: pr.branchId ? (current[pr.branchId] ?? \"\") : pr.revisionId,\n\t\t\t\tfirst: !!cs.chains.find((c) => c.contentId === pr.contentId)?.born,\n\t\t\t\tsupersedesReleaseIds: [...pr.supersedesReleaseIds],\n\t\t\t\tvalidityPeriod: pr.validityPeriod ? { ...pr.validityPeriod } : undefined,\n\t\t\t}));\n\t};\n\n\tfor (const [branchId, conflict] of Object.entries(conflicts)) {\n\t\tif (conflict.pending) storeMerge(branchId, conflict);\n\t}\n\n\tconst client: ContenthubClient = {\n\t\tasync listBlockReasons() {\n\t\t\treturn [...reasons].sort(byName).map((r) => ({ ...r }));\n\t\t},\n\t\tasync createBlockReason({ name: raw }) {\n\t\t\tconst name = checkedBlockReasonName(raw);\n\t\t\tif (taken(name)) throw new BlockReasonNameTakenError(name);\n\t\t\tconst reason = { id: `br_stub_${next++}`, name, createTime: now(), updateTime: now() };\n\t\t\treasons.push(reason);\n\t\t\treturn { ...reason };\n\t\t},\n\t\tasync renameBlockReason({ id, name: raw }) {\n\t\t\tconst name = checkedBlockReasonName(raw);\n\t\t\tconst reason = reasons.find((r) => r.id === id);\n\t\t\tif (!reason) throw notFound(\"Block Reason\", id);\n\t\t\tif (taken(name, id)) throw new BlockReasonNameTakenError(name);\n\t\t\treason.name = name;\n\t\t\treason.updateTime = now();\n\t\t\treturn { ...reason };\n\t\t},\n\t\tasync deleteBlockReason({ id }) {\n\t\t\tif (!reasons.some((r) => r.id === id)) throw notFound(\"Block Reason\", id);\n\t\t\treasons = reasons.filter((r) => r.id !== id);\n\t\t},\n\n\t\tasync listChangeSets(input = {}) {\n\t\t\tconst matching = changeSets.filter(\n\t\t\t\t(cs) =>\n\t\t\t\t\t(!input.state || cs.state === input.state) &&\n\t\t\t\t\t(!input.assigneeId || cs.assigneeIds.includes(input.assigneeId)) &&\n\t\t\t\t\t(!input.contentId || cs.chains.some((c) => c.contentId === input.contentId)) &&\n\t\t\t\t\t(!input.kind || (cs.kind ?? \"change_set\") === input.kind) &&\n\t\t\t\t\t(!input.editorId || cs.editorId === input.editorId),\n\t\t\t);\n\t\t\tconst size = Math.min(input.pageSize || 50, 200);\n\t\t\tconst start = input.pageToken ? Number(input.pageToken) : 0;\n\t\t\tconst page = matching.slice(start, start + size);\n\t\t\treturn {\n\t\t\t\t// A list carries no Chains, dependencies or Planned Releases.\n\t\t\t\tchangeSets: page.map((cs) => ({\n\t\t\t\t\t...copy(cs),\n\t\t\t\t\tchains: [],\n\t\t\t\t\tdependsOnChangeSetIds: [],\n\t\t\t\t\tplannedReleases: [],\n\t\t\t\t})),\n\t\t\t\tnextPageToken: start + size < matching.length ? String(start + size) : \"\",\n\t\t\t};\n\t\t},\n\t\tasync createChangeSet({ name: rawName, source }) {\n\t\t\tconst name = oneLine(rawName, \"name\", CHANGE_SET_NAME_MAX);\n\t\t\tconst checkedSource = source ? checkedSourceOf(source) : undefined;\n\t\t\tconst cs: ChangeSet = {\n\t\t\t\tid: `cs_stub_${next++}`,\n\t\t\t\tname,\n\t\t\t\tsource: checkedSource,\n\t\t\t\tstate: \"open\",\n\t\t\t\tcreatedBy: userId,\n\t\t\t\tcreateTime: now(),\n\t\t\t\tchains: [],\n\t\t\t\tdependsOnChangeSetIds: [],\n\t\t\t\tstatus: \"\",\n\t\t\t\tassigneeIds: [],\n\t\t\t\tplannedReleases: [],\n\t\t\t};\n\t\t\tchangeSets.unshift(cs);\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync getChangeSet(id) {\n\t\t\treturn copy(find(id));\n\t\t},\n\t\tasync updateChangeSet({ id, updateMask, name, source }) {\n\t\t\tconst cs = open(id);\n\t\t\tif (updateMask.length === 0) throw new InvalidInputError(\"update_mask is required\");\n\t\t\t// Checked whole before anything changes, as the service does.\n\t\t\tconst nextName = updateMask.includes(\"name\")\n\t\t\t\t? oneLine(name ?? \"\", \"name\", CHANGE_SET_NAME_MAX)\n\t\t\t\t: cs.name;\n\t\t\tlet nextSource = cs.source;\n\t\t\tif (updateMask.includes(\"source\")) {\n\t\t\t\tnextSource = source ? checkedSourceOf(source) : undefined;\n\t\t\t}\n\t\t\tcs.name = nextName;\n\t\t\tcs.source = nextSource;\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync setChangeSetStatus({ id, expectedStatus, status }) {\n\t\t\tconst cs = open(id);\n\t\t\tif (cs.status !== expectedStatus) throw new StaleStatusError(cs.status);\n\t\t\t// Already there: nothing to ask statushub, as the service does.\n\t\t\tif (cs.status === status) return copy(cs);\n\t\t\tif (!statuses.some((s) => s.slug === status)) {\n\t\t\t\tthrow new InvalidInputError(`status \"${status}\" is not in the workspace's catalogue`);\n\t\t\t}\n\t\t\t// A move away from an unknown status is never validated, so a Change\n\t\t\t// Set is never stuck on a deleted status (ADR 0014).\n\t\t\tconst known = statuses.some((s) => s.slug === cs.status);\n\t\t\tif (known && !(transitions[cs.status] ?? []).includes(status)) {\n\t\t\t\tthrow new StatusTransitionRefusedError({\n\t\t\t\t\tfromStatus: cs.status,\n\t\t\t\t\ttoStatus: status,\n\t\t\t\t\treason: `There is no transition from ${statusName(cs.status)} to ${statusName(status)}.`,\n\t\t\t\t\trequiresPermission: false,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcs.status = status;\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync setChangeSetAssignees({ id, assigneeIds }) {\n\t\t\tconst cs = find(id);\n\t\t\tif (new Set(assigneeIds).size !== assigneeIds.length) {\n\t\t\t\tthrow new InvalidInputError(\"each assignee is given once\");\n\t\t\t}\n\t\t\tif (assigneeIds.length > 50) throw new InvalidInputError(\"at most 50 assignees\");\n\t\t\tcs.assigneeIds = [...assigneeIds];\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync addDependency({ id, dependsOnId }) {\n\t\t\tconst cs = open(id);\n\t\t\tconst target = find(dependsOnId);\n\t\t\tif (target.state !== \"open\") {\n\t\t\t\tthrow new InvalidInputError(`Change Set ${dependsOnId} is ${target.state}`);\n\t\t\t}\n\t\t\tif (reaches(dependsOnId, id)) {\n\t\t\t\tthrow new InvalidInputError(\"the dependency would close a cycle\");\n\t\t\t}\n\t\t\tif (!cs.dependsOnChangeSetIds.includes(dependsOnId)) {\n\t\t\t\tcs.dependsOnChangeSetIds.push(dependsOnId);\n\t\t\t}\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync removeDependency({ id, dependsOnId }) {\n\t\t\tconst cs = open(id);\n\t\t\tif (!cs.dependsOnChangeSetIds.includes(dependsOnId)) {\n\t\t\t\tthrow notFound(`dependency of Change Set ${id} on`, dependsOnId);\n\t\t\t}\n\t\t\tcs.dependsOnChangeSetIds = cs.dependsOnChangeSetIds.filter((d) => d !== dependsOnId);\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync validatePublish({ id, reviewedHeads }) {\n\t\t\tconst cs = find(id);\n\t\t\trefuseWithheld(id);\n\t\t\tconst published = publishedWith.get(id);\n\t\t\t// Published with these heads: the stored outcome. With others, it is closed.\n\t\t\tif (published && sameHeads(published, reviewedHeads)) {\n\t\t\t\treturn {\n\t\t\t\t\tblockers: [],\n\t\t\t\t\treleases: releasesOf(cs),\n\t\t\t\t\tpublished: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (cs.state !== \"open\") throw new ChangeSetClosedError(cs.state);\n\t\t\treturn {\n\t\t\t\tblockers: blockersOf(cs, reviewedHeads),\n\t\t\t\treleases: releasesOf(cs),\n\t\t\t\tpublished: false,\n\t\t\t};\n\t\t},\n\t\tasync publish({ id, reviewedHeads }) {\n\t\t\tconst cs = find(id);\n\t\t\trefuseWithheld(id);\n\t\t\tconst published = publishedWith.get(id);\n\t\t\t// A repeat with the same heads returns the stored outcome.\n\t\t\tif (published && sameHeads(published, reviewedHeads)) {\n\t\t\t\treturn {\n\t\t\t\t\tchangeSet: copy(cs),\n\t\t\t\t\tpublishTime: cs.closeTime ?? now(),\n\t\t\t\t\treleases: releasesOf(cs),\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (cs.state !== \"open\") throw new ChangeSetClosedError(cs.state);\n\t\t\tconst blockers = blockersOf(cs, reviewedHeads);\n\t\t\tif (blockers.length > 0) throw new PublishRefusedError(blockers);\n\t\t\tconst cut = releasesOf(cs);\n\t\t\tcs.state = \"published\";\n\t\t\tcs.closeTime = now();\n\t\t\tpublishedWith.set(id, { ...reviewedHeads });\n\t\t\treturn { changeSet: copy(cs), publishTime: cs.closeTime, releases: cut };\n\t\t},\n\t\tasync changeValidity({ releaseId, validityPeriod, changeSetName, idempotencyKey }) {\n\t\t\treturn once(\n\t\t\t\tidempotencyKey,\n\t\t\t\t[\"changeValidity\", releaseId, validityPeriod, changeSetName],\n\t\t\t\tasync () => {\n\t\t\t\t\tconst c = contents.find((each) =>\n\t\t\t\t\t\t(each.timeline ?? []).some((e) => e.releaseId === releaseId),\n\t\t\t\t\t);\n\t\t\t\t\tif (!c) throw notFound(\"Release\", releaseId);\n\t\t\t\t\tcheckEditable(c);\n\t\t\t\t\tconst timeline = c.timeline ?? [];\n\t\t\t\t\tconst entry = timeline.find((e) => e.releaseId === releaseId);\n\t\t\t\t\tif (!entry?.validityPeriod || !datedContent(c)) {\n\t\t\t\t\t\tthrow new InvalidInputError(\"undated Releases carry no Validity Period\");\n\t\t\t\t\t}\n\t\t\t\t\tconst { firstDay, lastDay = \"\" } = validityPeriod;\n\t\t\t\t\tif (\n\t\t\t\t\t\t!DAY.test(firstDay) ||\n\t\t\t\t\t\t(lastDay !== \"\" && (!DAY.test(lastDay) || lastDay < firstDay))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t\t\"validity_period is YYYY-MM-DD, the last day not before the first\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// \"Change Sets only\" refuses it, as it refuses a Direct Edit (ADR 0022).\n\t\t\t\t\tconst accessor = resolved[c.blueprintReleaseId]?.accessor ?? \"\";\n\t\t\t\t\tconst override = editingOverrides.find((o) => o.blueprintAccessor === accessor);\n\t\t\t\t\tif (effectiveOf(override).editingMode === \"change_sets\") {\n\t\t\t\t\t\tthrow new EditingModeRefusedError(c.id, accessor);\n\t\t\t\t\t}\n\t\t\t\t\tconst covered = timeline\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(e) =>\n\t\t\t\t\t\t\t\te.releaseId !== releaseId &&\n\t\t\t\t\t\t\t\te.validityPeriod &&\n\t\t\t\t\t\t\t\tfirstDay <= e.validityPeriod.firstDay &&\n\t\t\t\t\t\t\t\t(lastDay === \"\" ||\n\t\t\t\t\t\t\t\t\t(e.validityPeriod.lastDay !== \"\" && e.validityPeriod.lastDay <= lastDay)),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.map((e) => e.releaseId);\n\t\t\t\t\tif (covered.length > 0) throw new CoversReleaseError(c.id, covered, true);\n\t\t\t\t\tconst plannedRelease = {\n\t\t\t\t\t\tid: `rls_stub_${next++}`,\n\t\t\t\t\t\tcontentId: c.id,\n\t\t\t\t\t\tkind: \"date_only\" as const,\n\t\t\t\t\t\tbranchId: \"\",\n\t\t\t\t\t\trevisionId: entry.revisionId,\n\t\t\t\t\t\tvalidityPeriod: { firstDay, lastDay },\n\t\t\t\t\t\tsupersedesReleaseIds: [releaseId],\n\t\t\t\t\t\tproposed: false,\n\t\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\t\twithheld: false,\n\t\t\t\t\t};\n\t\t\t\t\tconst cs: ChangeSet = {\n\t\t\t\t\t\tid: `cs_stub_${next++}`,\n\t\t\t\t\t\tname: changeSetName?.trim() || `Change of validity of ${c.id}`,\n\t\t\t\t\t\tstate: \"open\",\n\t\t\t\t\t\tcreatedBy: userId,\n\t\t\t\t\t\tcreateTime: now(),\n\t\t\t\t\t\tchains: [],\n\t\t\t\t\t\tdependsOnChangeSetIds: [],\n\t\t\t\t\t\tstatus: \"\",\n\t\t\t\t\t\tassigneeIds: [],\n\t\t\t\t\t\tplannedReleases: [plannedRelease],\n\t\t\t\t\t};\n\t\t\t\t\t// Refused as a whole: the Change Set is never kept.\n\t\t\t\t\tconst blockers = blockersOf(cs, {});\n\t\t\t\t\tif (blockers.length > 0) throw new PublishRefusedError(blockers);\n\t\t\t\t\tconst cut = releasesOf(cs);\n\t\t\t\t\tcs.state = \"published\";\n\t\t\t\t\tcs.closeTime = now();\n\t\t\t\t\tchangeSets.unshift(cs);\n\t\t\t\t\tpublishedWith.set(cs.id, {});\n\t\t\t\t\tc.timeline = timeline.map((e) =>\n\t\t\t\t\t\te.releaseId === releaseId\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t...e,\n\t\t\t\t\t\t\t\t\treleaseId: plannedRelease.id,\n\t\t\t\t\t\t\t\t\tkind: \"date_only\",\n\t\t\t\t\t\t\t\t\tvalidityPeriod: { firstDay, lastDay },\n\t\t\t\t\t\t\t\t\tpublishTime: cs.closeTime ?? now(),\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: e,\n\t\t\t\t\t);\n\t\t\t\t\treturn { changeSet: copy(cs), publishTime: cs.closeTime, releases: cut };\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync updateFromMain({ id, chainId, idempotencyKey }) {\n\t\t\treturn once(idempotencyKey, [\"updateFromMain\", id, chainId], async () => {\n\t\t\t\tconst cs = open(id);\n\t\t\t\tif (!chainId) refuseWithheld(id);\n\t\t\t\tconst chains = chainId ? cs.chains.filter((ch) => ch.id === chainId) : cs.chains;\n\t\t\t\tif (chainId && chains.length === 0) throw notFound(\"Chain\", chainId);\n\t\t\t\tconst conflicted: PendingMergeRef[] = structuredClone(pendingMerges[id] ?? []);\n\t\t\t\tconst pending: PendingMergeRef[] = [];\n\t\t\t\tfor (const chain of chains) {\n\t\t\t\t\tfor (const b of chain.branches) {\n\t\t\t\t\t\tconst ref = { branchId: b.id, contentId: chain.contentId };\n\t\t\t\t\t\tconst conflict = conflicts[b.id];\n\t\t\t\t\t\tif (stored.has(b.id)) pending.push(ref);\n\t\t\t\t\t\telse if (conflict) {\n\t\t\t\t\t\t\tstoreMerge(b.id, conflict);\n\t\t\t\t\t\t\tconflicted.push(ref);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tchangeSet: copy(cs),\n\t\t\t\t\tmergedBranchIds: [],\n\t\t\t\t\tconflicted,\n\t\t\t\t\tpending,\n\t\t\t\t\tendedBranchIds: [],\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\tasync discardChangeSet(id) {\n\t\t\tconst cs = open(id);\n\t\t\trefuseWithheld(id);\n\t\t\tcs.state = \"discarded\";\n\t\t\tcs.closeTime = now();\n\t\t\t// The Content born in it is gone, and its Chains with it.\n\t\t\tcs.chains = [];\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync listCheckResults(changeSetId) {\n\t\t\treturn standingsOf(find(changeSetId));\n\t\t},\n\t\tasync recordCheckResult({ changeSetId, requiredCheckId, heads, outcome, note }) {\n\t\t\tconst cs = open(changeSetId);\n\t\t\tif (outcome === \"waived\" && note.trim() === \"\") {\n\t\t\t\tthrow new InvalidInputError(\"a waived result needs a note saying why\");\n\t\t\t}\n\t\t\tif ([...note].length > CHECK_NOTE_MAX) {\n\t\t\t\tthrow new InvalidInputError(`a note is at most ${CHECK_NOTE_MAX} characters`);\n\t\t\t}\n\t\t\tconst check = requiredChecks.find((c) => c.id === requiredCheckId);\n\t\t\tif (!check) throw notFound(\"Required Check\", requiredCheckId);\n\t\t\tconst recording = recordersOf(requiredCheckId);\n\t\t\t// The caller is a member: the stub has no other kind of caller.\n\t\t\tif (\n\t\t\t\tauthzMode === \"guardian\" &&\n\t\t\t\t!recording.everyMember &&\n\t\t\t\t!recording.userIds.includes(userId)\n\t\t\t) {\n\t\t\t\tthrow new CheckResultDeniedError(\n\t\t\t\t\t`recording results of Required Check ${requiredCheckId} needs its recorder relation`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst subjects = subjectsOf(cs);\n\t\t\tconst named = Object.keys(heads);\n\t\t\tif (check.scope === \"branch\" && named.length !== 1) {\n\t\t\t\tthrow new InvalidInputError(\"a Branch-scope result names one head\");\n\t\t\t}\n\t\t\tif (check.scope === \"change_set\" && named.length !== subjects.length) {\n\t\t\t\tthrow new InvalidInputError(\"a Change Set-scope result names every head of the Change Set\");\n\t\t\t}\n\t\t\tfor (const key of named) {\n\t\t\t\tconst s = subjects.find((each) => each.key === key);\n\t\t\t\tif (!s)\n\t\t\t\t\tthrow new InvalidInputError(`heads name ${key}, which this Change Set doesn't hold`);\n\t\t\t\tif (s.revision !== heads[key]) {\n\t\t\t\t\tthrow new StaleHeadError({\n\t\t\t\t\t\tcontentId: s.contentId,\n\t\t\t\t\t\tbranchId: s.branchless ? \"\" : s.key,\n\t\t\t\t\t\texpectedHeadId: heads[key],\n\t\t\t\t\t\tcurrentHeadId: s.revision,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst result = {\n\t\t\t\tid: `cr_stub_${next++}`,\n\t\t\t\trequiredCheckId,\n\t\t\t\theads: { ...heads },\n\t\t\t\toutcome,\n\t\t\t\tnote,\n\t\t\t\trecordedBy: userId,\n\t\t\t\trecordTime: now(),\n\t\t\t};\n\t\t\tcheckResults.push({ ...result, changeSetId });\n\t\t\treturn structuredClone(result);\n\t\t},\n\n\t\tasync getEditingSettings() {\n\t\t\tconst byAccessor = [...editingOverrides].sort((a, b) =>\n\t\t\t\ta.blueprintAccessor < b.blueprintAccessor ? -1 : 1,\n\t\t\t);\n\t\t\treturn { workspace: { ...workspaceEditing }, overrides: byAccessor.map(overrideOut) };\n\t\t},\n\t\tasync getEffectiveEditingSettings(blueprintAccessor) {\n\t\t\tconst o = editingOverrides.find((x) => x.blueprintAccessor === blueprintAccessor.trim());\n\t\t\treturn {\n\t\t\t\teffective: effectiveOf(o),\n\t\t\t\teditingModeOverridden: (o?.editingMode ?? null) !== null,\n\t\t\t\teditingBlockOverridden: (o?.editingBlock ?? null) !== null,\n\t\t\t};\n\t\t},\n\t\tasync setEditingSettings(settings) {\n\t\t\tadminOnly();\n\t\t\tif (!editingModes.includes(settings.editingMode)) {\n\t\t\t\tthrow new InvalidInputError(\"the workspace's editing settings need an Editing Mode\");\n\t\t\t}\n\t\t\tworkspaceEditing = { ...settings };\n\t\t\treturn { ...workspaceEditing };\n\t\t},\n\t\tasync setBlueprintEditingOverride({ blueprintAccessor, editingMode, editingBlock }) {\n\t\t\tadminOnly();\n\t\t\tconst accessor = oneLine(blueprintAccessor, \"a Blueprint accessor\", BLUEPRINT_ACCESSOR_MAX);\n\t\t\tif (editingMode === null && editingBlock === null) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`an override of \"${accessor}\" sets the Editing Mode, the Editing Block or both`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst o: StubEditingOverride = { blueprintAccessor: accessor, editingMode, editingBlock };\n\t\t\teditingOverrides = [...editingOverrides.filter((x) => x.blueprintAccessor !== accessor), o];\n\t\t\treturn overrideOut(o);\n\t\t},\n\t\tasync deleteBlueprintEditingOverride({ blueprintAccessor }) {\n\t\t\tadminOnly();\n\t\t\tconst accessor = blueprintAccessor.trim();\n\t\t\tif (!editingOverrides.some((x) => x.blueprintAccessor === accessor)) {\n\t\t\t\tthrow notFound(\"an editing override of\", accessor);\n\t\t\t}\n\t\t\teditingOverrides = editingOverrides.filter((x) => x.blueprintAccessor !== accessor);\n\t\t},\n\n\t\tasync listRequiredChecks() {\n\t\t\tconst byNameThenId = (a: RequiredCheck, b: RequiredCheck) =>\n\t\t\t\ta.name < b.name ? -1 : a.name > b.name ? 1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\t\t\treturn structuredClone([...requiredChecks].sort(byNameThenId));\n\t\t},\n\t\tasync createRequiredCheck(input) {\n\t\t\tconst checked = checkedRequiredCheck(input);\n\t\t\tif (requiredChecks.some((c) => c.name === checked.name)) {\n\t\t\t\tthrow new NameTakenError(checked.name);\n\t\t\t}\n\t\t\tconst check: RequiredCheck = { id: `rc_stub_${next++}`, ...checked };\n\t\t\trequiredChecks.push(check);\n\t\t\treturn structuredClone(check);\n\t\t},\n\t\tasync updateRequiredCheck({ id, ...input }) {\n\t\t\tconst checked = checkedRequiredCheck(input);\n\t\t\tconst check = requiredChecks.find((c) => c.id === id);\n\t\t\tif (!check) throw notFound(\"Required Check\", id);\n\t\t\tif (requiredChecks.some((c) => c.name === checked.name && c.id !== id)) {\n\t\t\t\tthrow new NameTakenError(checked.name);\n\t\t\t}\n\t\t\tObject.assign(check, checked);\n\t\t\treturn structuredClone(check);\n\t\t},\n\t\tasync deleteRequiredCheck({ id }) {\n\t\t\tif (!requiredChecks.some((c) => c.id === id)) throw notFound(\"Required Check\", id);\n\t\t\trequiredChecks = requiredChecks.filter((c) => c.id !== id);\n\t\t\trecorders.delete(id);\n\t\t},\n\t\tasync listRequiredCheckRecorders(requiredCheckId) {\n\t\t\treturn structuredClone(narrowable(requiredCheckId));\n\t\t},\n\t\tasync grantRequiredCheckRecorder({ requiredCheckId, recorder }) {\n\t\t\tconst held = narrowable(requiredCheckId);\n\t\t\tif (\"everyMember\" in recorder) {\n\t\t\t\trecorders.set(requiredCheckId, { ...held, everyMember: true });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!memberIds.includes(recorder.userId)) {\n\t\t\t\tthrow new InvalidInputError(`user ${recorder.userId} is not a member of the workspace`);\n\t\t\t}\n\t\t\trecorders.set(requiredCheckId, {\n\t\t\t\t...held,\n\t\t\t\tuserIds: [...new Set([...held.userIds, recorder.userId])].sort(),\n\t\t\t});\n\t\t},\n\t\tasync revokeRequiredCheckRecorder({ requiredCheckId, recorder }) {\n\t\t\tconst held = narrowable(requiredCheckId);\n\t\t\trecorders.set(\n\t\t\t\trequiredCheckId,\n\t\t\t\t\"everyMember\" in recorder\n\t\t\t\t\t? { ...held, everyMember: false }\n\t\t\t\t\t: { ...held, userIds: held.userIds.filter((u) => u !== recorder.userId) },\n\t\t\t);\n\t\t},\n\n\t\tasync searchBlueprints({ query }) {\n\t\t\tconst q = query.trim().toLocaleLowerCase();\n\t\t\treturn {\n\t\t\t\tblueprints: blueprints\n\t\t\t\t\t.filter((b) => !b.archived)\n\t\t\t\t\t.filter((b) => b.name.toLocaleLowerCase().includes(q))\n\t\t\t\t\t.filter((b) => releases.some((r) => r.blueprintId === b.id))\n\t\t\t\t\t.map((b) => ({ id: b.id, name: b.name })),\n\t\t\t\tnextPageToken: \"\",\n\t\t\t};\n\t\t},\n\t\tasync getBlueprints(ids) {\n\t\t\tif (ids.length > MAX_BLUEPRINT_IDS) {\n\t\t\t\tthrow new InvalidInputError(`at most ${MAX_BLUEPRINT_IDS} Blueprint ids`);\n\t\t\t}\n\t\t\treturn blueprints.filter((b) => ids.includes(b.id)).map((b) => ({ id: b.id, name: b.name }));\n\t\t},\n\t\tasync listBlueprintReleases(blueprintId) {\n\t\t\treturn releases\n\t\t\t\t.filter((r) => r.blueprintId === blueprintId)\n\t\t\t\t.map((r) => ({\n\t\t\t\t\tid: r.id,\n\t\t\t\t\tblueprintId: r.blueprintId,\n\t\t\t\t\tname: r.name ?? r.id,\n\t\t\t\t\treleaseTime: r.releaseTime ?? STUB_NOW,\n\t\t\t\t\trefusals: (r.refusals ?? []).map((v) => ({ ...v })),\n\t\t\t\t}));\n\t\t},\n\n\t\tasync listCollections() {\n\t\t\treturn [...collections].sort(collectionOrder).map((c) => ({ ...c }));\n\t\t},\n\t\tasync createCollection({ name: raw, parentId = \"\", restricted = false }) {\n\t\t\tconst name = oneLine(raw, \"a Collection's name\", COLLECTION_NAME_MAX);\n\t\t\tif (parentId !== \"\") findCollection(parentId);\n\t\t\tif (restricted && authzMode === \"workspace\") {\n\t\t\t\tthrow new RestrictionUnavailableError(WORKSPACE_MODE_REFUSAL);\n\t\t\t}\n\t\t\tif (siblingNamed(parentId, name)) throw new NameTakenError(name);\n\t\t\tconst collection: Collection = { id: `col_stub_${next++}`, name, parentId, restricted };\n\t\t\tcollections.push(collection);\n\t\t\tif (restricted) grants.set(collection.id, [{ userId, level: \"owner\" }]);\n\t\t\treturn { ...collection };\n\t\t},\n\t\tasync renameCollection({ id, name: raw }) {\n\t\t\tconst name = oneLine(raw, \"a Collection's name\", COLLECTION_NAME_MAX);\n\t\t\tconst collection = findCollection(id);\n\t\t\tif (siblingNamed(collection.parentId, name, id)) throw new NameTakenError(name);\n\t\t\tcollection.name = name;\n\t\t\treturn { ...collection };\n\t\t},\n\t\tasync moveCollection({ id, parentId }) {\n\t\t\tconst collection = findCollection(id);\n\t\t\tfor (let at = parentId; at !== \"\"; at = findCollection(at).parentId) {\n\t\t\t\tif (at === id) {\n\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t`Collection ${id} can't move under itself or a Collection under it`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// As over the wire: a move sends no name, so the refusal names none.\n\t\t\tif (siblingNamed(parentId, collection.name, id)) throw new NameTakenError(\"\");\n\t\t\tcollection.parentId = parentId;\n\t\t\treturn { ...collection };\n\t\t},\n\t\tasync removeCollection({ id }) {\n\t\t\tfindCollection(id);\n\t\t\tif (collections.some((c) => c.parentId === id)) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`Collection ${id} has Collections under it: remove or move those first`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcollections.splice(\n\t\t\t\tcollections.findIndex((c) => c.id === id),\n\t\t\t\t1,\n\t\t\t);\n\t\t\tgrants.delete(id);\n\t\t\tconst unfiled: string[] = [];\n\t\t\tfor (const c of contents) {\n\t\t\t\tif (c.collectionIds.includes(id)) {\n\t\t\t\t\tc.collectionIds = c.collectionIds.filter((each) => each !== id);\n\t\t\t\t\tunfiled.push(c.id);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn unfiled;\n\t\t},\n\t\tasync setCollectionRestricted({ id, restricted, acknowledgeDisclosure = false }) {\n\t\t\tif (restricted && authzMode === \"workspace\") {\n\t\t\t\tthrow new RestrictionUnavailableError(WORKSPACE_MODE_REFUSAL);\n\t\t\t}\n\t\t\tconst collection = findCollection(id);\n\t\t\tif (collection.restricted === restricted) return { ...collection };\n\t\t\tif (!restricted && !acknowledgeDisclosure) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`unrestricting Collection ${id} discloses its Content to every viewer: ` +\n\t\t\t\t\t\t\"confirm it with acknowledge_disclosure\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tcollection.restricted = restricted;\n\t\t\t// The one who restricts it owns it; opening it clears every grant.\n\t\t\tif (restricted) grants.set(id, [{ userId, level: \"owner\" }]);\n\t\t\telse grants.delete(id);\n\t\t\treturn { ...collection };\n\t\t},\n\t\tasync listCollectionGrants(collectionId) {\n\t\t\tmanageable(collectionId);\n\t\t\treturn structuredClone(grants.get(collectionId) ?? []).sort((a, b) =>\n\t\t\t\ta.userId < b.userId ? -1 : a.userId > b.userId ? 1 : 0,\n\t\t\t);\n\t\t},\n\t\tasync grantCollectionAccess({ collectionId, userId: grantee, level }) {\n\t\t\tmanageable(collectionId);\n\t\t\tif (level !== \"viewer\" && level !== \"editor\") {\n\t\t\t\tthrow new InvalidInputError(\"a grant is viewer or editor\");\n\t\t\t}\n\t\t\tif (!memberIds.includes(grantee)) {\n\t\t\t\tthrow new InvalidInputError(`${grantee} is not a member of the workspace`);\n\t\t\t}\n\t\t\tconst held = grants.get(collectionId) ?? [];\n\t\t\t// The owner stays owner: a grant never lowers what restricting gave.\n\t\t\tif (held.some((g) => g.level === \"owner\" && g.userId === grantee)) return;\n\t\t\tgrants.set(collectionId, [\n\t\t\t\t...held.filter((g) => g.userId !== grantee),\n\t\t\t\t{ userId: grantee, level },\n\t\t\t]);\n\t\t},\n\t\tasync revokeCollectionAccess({ collectionId, userId: grantee }) {\n\t\t\tmanageable(collectionId);\n\t\t\tgrants.set(\n\t\t\t\tcollectionId,\n\t\t\t\t(grants.get(collectionId) ?? []).filter((g) => g.userId !== grantee || g.level === \"owner\"),\n\t\t\t);\n\t\t},\n\t\tasync listContents(input = {}) {\n\t\t\tconst view: ContentView = input.view ?? { kind: \"main\" };\n\t\t\tconst search = (input.search ?? \"\").trim();\n\t\t\tif (search !== \"\" && view.kind === \"in_force\") {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\"filter.search: Editor Search covers Main and open Branch heads, never Releases\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif ([...search].length > CONTENT_SEARCH_MAX) {\n\t\t\t\tthrow new InvalidInputError(`filter.search is at most ${CONTENT_SEARCH_MAX} characters`);\n\t\t\t}\n\t\t\tif (input.collectionId && !collections.some((c) => c.id === input.collectionId)) {\n\t\t\t\tthrow notFound(\"Collection\", input.collectionId);\n\t\t\t}\n\t\t\tif (view.kind === \"change_set\") find(view.changeSetId);\n\n\t\t\tconst rows = contents\n\t\t\t\t// Archived Content is put aside: every view leaves it out (ADR 0015).\n\t\t\t\t.filter((c) => !c.archiveTime)\n\t\t\t\t.filter((c) => !input.collectionId || c.collectionIds.includes(input.collectionId))\n\t\t\t\t.filter((c) => !input.blueprintIds?.length || input.blueprintIds.includes(c.blueprintId))\n\t\t\t\t.filter((c) => !input.assigneeId || (c.assigneeIds ?? []).includes(input.assigneeId))\n\t\t\t\t.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n\t\t\t\t.flatMap((c) => readsOf(c, view, search));\n\t\t\tconst size = Math.min(input.pageSize || 50, 200);\n\t\t\tconst start = input.pageToken ? Number(input.pageToken) : 0;\n\t\t\treturn {\n\t\t\t\tcontents: rows.slice(start, start + size),\n\t\t\t\tnextPageToken: start + size < rows.length ? String(start + size) : \"\",\n\t\t\t};\n\t\t},\n\t\tasync createContent({ changeSetId, blueprintReleaseId: asked, copyFrom }) {\n\t\t\tconst cs = open(changeSetId);\n\t\t\tlet data: Record<string, unknown> = {};\n\t\t\tlet blueprintReleaseId = asked;\n\t\t\tif (copyFrom) {\n\t\t\t\tconst sourceRevision =\n\t\t\t\t\t\"revisionId\" in copyFrom\n\t\t\t\t\t\t? copyFrom.revisionId\n\t\t\t\t\t\t: contents.find((c) => c.inForce?.releaseId === copyFrom.releaseId)?.inForce\n\t\t\t\t\t\t\t\t?.revisionId;\n\t\t\t\tconst source = contents.find((c) => sourceRevision && dataOf(c, sourceRevision));\n\t\t\t\tif (!source || !sourceRevision) {\n\t\t\t\t\tthrow notFound(\"copy source\", JSON.stringify(copyFrom));\n\t\t\t\t}\n\t\t\t\tdata = structuredClone(dataOf(source, sourceRevision) ?? {});\n\t\t\t\tblueprintReleaseId = asked || source.blueprintReleaseId;\n\t\t\t}\n\t\t\tconst release = releases.find((r) => r.id === blueprintReleaseId);\n\t\t\tif (!release) {\n\t\t\t\tthrow new ContentRefusedError(`Blueprint Release ${blueprintReleaseId} can't be loaded`, [\n\t\t\t\t\t{ source: \"contenthub\", code: \"release_not_found\", path: \"\" },\n\t\t\t\t]);\n\t\t\t}\n\t\t\tif (release.refusals?.length) {\n\t\t\t\tthrow new ContentRefusedError(\n\t\t\t\t\t`Blueprint Release ${blueprintReleaseId} can't be loaded`,\n\t\t\t\t\trelease.refusals.map((r) => ({ ...r })),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst n = next++;\n\t\t\tconst id = `content_stub_${n}`;\n\t\t\tconst branchId = `br_stub_${n}`;\n\t\t\tconst revisionId = `rev_stub_${n}`;\n\t\t\tcontents.push({\n\t\t\t\tid,\n\t\t\t\tblueprintId: release.blueprintId,\n\t\t\t\tblueprintReleaseId,\n\t\t\t\tcollectionIds: [],\n\t\t\t\tbranches: {\n\t\t\t\t\t[changeSetId]: { branchId, revisionId, data, revisionCreateTime: now() },\n\t\t\t\t},\n\t\t\t});\n\t\t\tcs.chains.push({\n\t\t\t\tid: `chain_stub_${n}`,\n\t\t\t\tcontentId: id,\n\t\t\t\tborn: true,\n\t\t\t\tbranches: [{ id: branchId, position: 0, kind: \"editorial\", headRevisionId: revisionId }],\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tblueprintId: release.blueprintId,\n\t\t\t\tblueprintReleaseId,\n\t\t\t\trevisionId,\n\t\t\t\tdata: structuredClone(data),\n\t\t\t\tchangeSetId,\n\t\t\t\tbranchId,\n\t\t\t\trevisionCreateTime: now(),\n\t\t\t\treleaseId: \"\",\n\t\t\t};\n\t\t},\n\n\t\tasync saveRevision({ idempotencyKey, ...request }) {\n\t\t\tif (!idempotencyKey) return saveOnce(request);\n\t\t\t// A repeat answers the first save and writes nothing; another\n\t\t\t// request under the same key is refused (CONTEXT.md, Idempotency Key).\n\t\t\tconst asked = JSON.stringify(request);\n\t\t\tconst kept = savedUnder.get(idempotencyKey);\n\t\t\tif (kept) {\n\t\t\t\tif (kept.asked !== asked) {\n\t\t\t\t\tthrow new InvalidInputError(`idempotency key ${idempotencyKey} names another save`);\n\t\t\t\t}\n\t\t\t\treturn structuredClone(kept.content);\n\t\t\t}\n\t\t\tconst content = await saveOnce(request);\n\t\t\tsavedUnder.set(idempotencyKey, { asked, content: structuredClone(content) });\n\t\t\treturn content;\n\t\t},\n\n\t\tasync getContent({ id, changeSetId, branchId }) {\n\t\t\tconst c = findContent(id);\n\t\t\tconst view: ContentView = changeSetId\n\t\t\t\t? { kind: \"change_set\", changeSetId }\n\t\t\t\t: { kind: \"main\" };\n\t\t\tif (branchId && !changeSetId) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\"branch_id names a Branch of a Change Set: give its change_set_id too\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Born in an open Change Set, it exists only there, as the service says.\n\t\t\tlet [content] = readsOf(c, view, \"\");\n\t\t\tif (!content) throw notFound(\"Content\", id);\n\t\t\tif (branchId && branchId !== content.branchId) {\n\t\t\t\t// An earlier Branch of the Chain, at its own head.\n\t\t\t\tconst branch = changeSets\n\t\t\t\t\t.find((cs) => cs.id === changeSetId)\n\t\t\t\t\t?.chains.find((ch) => ch.contentId === id)\n\t\t\t\t\t?.branches.find((b) => b.id === branchId);\n\t\t\t\tif (!branch) throw notFound(\"Branch\", branchId);\n\t\t\t\tconst rev = revisionsOf(c).find((r) => r.id === branch.headRevisionId);\n\t\t\t\tconst data = rev?.data ?? (c.main?.revisionId === branch.headRevisionId ? c.main.data : {});\n\t\t\t\tcontent = {\n\t\t\t\t\t...content,\n\t\t\t\t\trevisionId: branch.headRevisionId,\n\t\t\t\t\tdata: structuredClone(data),\n\t\t\t\t\tbranchId,\n\t\t\t\t\trevisionCreateTime: rev?.createTime ?? content.revisionCreateTime,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst release = resolved[c.blueprintReleaseId];\n\t\t\treturn {\n\t\t\t\tcontent,\n\t\t\t\tblueprintRelease: release ? structuredClone(release) : undefined,\n\t\t\t\tattributes: attributesOf(c),\n\t\t\t};\n\t\t},\n\t\tasync getTimeline(contentId) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tconst isOpen = (csId: string) => changeSets.find((cs) => cs.id === csId)?.state === \"open\";\n\t\t\treturn structuredClone({\n\t\t\t\tentries: c.timeline ?? [],\n\t\t\t\tplannedReleases: (c.plannedReleases ?? []).filter((p) => isOpen(p.changeSetId)),\n\t\t\t});\n\t\t},\n\t\tasync listRevisions({ target, pageSize, pageToken }) {\n\t\t\tlet found: (Revision & { data?: unknown })[];\n\t\t\tif (\"contentId\" in target) {\n\t\t\t\tconst c = findContent(target.contentId);\n\t\t\t\t// versionkit lists by Item only once it is published (#65).\n\t\t\t\tif (!c.main) throw notFound(\"Content\", target.contentId);\n\t\t\t\tfound = revisionsOf(c);\n\t\t\t} else {\n\t\t\t\tconst owner = contents.find((c) =>\n\t\t\t\t\trevisionsOf(c).some((r) => r.branchId === target.branchId),\n\t\t\t\t);\n\t\t\t\tif (!owner) throw notFound(\"Branch\", target.branchId);\n\t\t\t\tfound = revisionsOf(owner).filter((r) => r.branchId === target.branchId);\n\t\t\t}\n\t\t\tconst size = Math.min(pageSize || 50, 200);\n\t\t\tconst start = pageToken ? Number(pageToken) : 0;\n\t\t\treturn {\n\t\t\t\trevisions: found.slice(start, start + size).map(({ data: _data, ...r }) => r),\n\t\t\t\tnextPageToken: start + size < found.length ? String(start + size) : \"\",\n\t\t\t};\n\t\t},\n\t\tasync compare({ revisionId, base }) {\n\t\t\tconst c = contents.find((each) => revisionsOf(each).some((r) => r.id === revisionId));\n\t\t\tif (!c) throw notFound(\"Revision\", revisionId);\n\t\t\tconst all = revisionsOf(c);\n\t\t\tconst after = all.find((r) => r.id === revisionId) as Revision;\n\t\t\tlet baseId: string;\n\t\t\tif (base.kind === \"revision\") baseId = base.revisionId;\n\t\t\telse if (base.kind === \"main_head\") {\n\t\t\t\tif (!c.main) {\n\t\t\t\t\tthrow new InvalidInputError(\"the Content is not published: it has no Main Branch\");\n\t\t\t\t}\n\t\t\t\tbaseId = c.main.revisionId;\n\t\t\t} else baseId = all.find((r) => r.branchId === base.branchId)?.parentId ?? \"\";\n\t\t\tconst before = all.find((r) => r.id === baseId);\n\t\t\tif (!before) throw notFound(\"Revision\", baseId);\n\t\t\tconst a = dataOf(c, after.id) ?? {};\n\t\t\tconst b = dataOf(c, before.id) ?? {};\n\t\t\tconst changes: FieldChange[] = [];\n\t\t\tfor (const key of [...new Set([...Object.keys(a), ...Object.keys(b)])]) {\n\t\t\t\tif (!(key in b)) changes.push({ path: `/${key}`, kind: \"added\", after: a[key] });\n\t\t\t\telse if (!(key in a)) changes.push({ path: `/${key}`, kind: \"removed\", before: b[key] });\n\t\t\t\telse if (JSON.stringify(a[key]) !== JSON.stringify(b[key])) {\n\t\t\t\t\tchanges.push({ path: `/${key}`, kind: \"changed\", before: b[key], after: a[key] });\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst strip = ({ data: _data, ...r }: Revision & { data?: unknown }) => r;\n\t\t\treturn { base: strip(before), revision: strip(after), changes };\n\t\t},\n\t\tasync listReferences({ contentId, revisionId }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\treturn (c.edges ?? [])\n\t\t\t\t.filter((e) => e.sourceRevisionId === revisionId)\n\t\t\t\t.map((e) => ({ ...e }));\n\t\t},\n\t\tasync listReferrers({ contentId, includeOpenChangeSets, pageSize, pageToken }) {\n\t\t\tfindContent(contentId);\n\t\t\t// Paged as the service pages, by position in its order.\n\t\t\tconst page = (rows: Referrer[]): ReferrerList => {\n\t\t\t\tconst size = Math.min(pageSize || 100, 1000);\n\t\t\t\tconst start = pageToken ? Number(pageToken) : 0;\n\t\t\t\treturn {\n\t\t\t\t\treferrers: rows.slice(start, start + size),\n\t\t\t\t\tnextPageToken: start + size < rows.length ? String(start + size) : \"\",\n\t\t\t\t};\n\t\t\t};\n\t\t\tconst fromReleases = contents.flatMap((other) =>\n\t\t\t\t(other.edges ?? [])\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(e) =>\n\t\t\t\t\t\t\te.targetContentId === contentId && other.inForce?.revisionId === e.sourceRevisionId,\n\t\t\t\t\t)\n\t\t\t\t\t.map((e) => ({\n\t\t\t\t\t\tedge: { ...e },\n\t\t\t\t\t\treleaseId: other.inForce?.releaseId ?? \"\",\n\t\t\t\t\t\tchangeSetId: \"\",\n\t\t\t\t\t\tbranchId: \"\",\n\t\t\t\t\t})),\n\t\t\t);\n\t\t\tif (!includeOpenChangeSets) return page(fromReleases);\n\t\t\tconst fromBranches = contents.flatMap((other) =>\n\t\t\t\tObject.entries(other.branches).flatMap(([csId, head]) =>\n\t\t\t\t\tchangeSets.find((cs) => cs.id === csId)?.state !== \"open\"\n\t\t\t\t\t\t? []\n\t\t\t\t\t\t: (other.edges ?? [])\n\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t(e) => e.targetContentId === contentId && e.sourceRevisionId === head.revisionId,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.map((e) => ({\n\t\t\t\t\t\t\t\t\tedge: { ...e },\n\t\t\t\t\t\t\t\t\treleaseId: \"\",\n\t\t\t\t\t\t\t\t\tchangeSetId: csId,\n\t\t\t\t\t\t\t\t\tbranchId: head.branchId,\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn page([...fromReleases, ...fromBranches]);\n\t\t},\n\t\tasync listOutdatedPins(input) {\n\t\t\tlet revisionId: string | undefined;\n\t\t\tif (\"revisionId\" in input) revisionId = input.revisionId;\n\t\t\telse {\n\t\t\t\tfor (const c of contents) {\n\t\t\t\t\tconst head = Object.values(c.branches).find((h) => h.branchId === input.branchId);\n\t\t\t\t\tif (head) revisionId = head.revisionId;\n\t\t\t\t}\n\t\t\t\tif (!revisionId) throw notFound(\"Branch\", input.branchId);\n\t\t\t}\n\t\t\tconst edges: Edge[] = contents.flatMap((c) =>\n\t\t\t\t(c.edges ?? []).filter((e) => e.sourceRevisionId === revisionId),\n\t\t\t);\n\t\t\treturn edges\n\t\t\t\t.filter((e) => e.pinReleaseId !== \"\")\n\t\t\t\t.flatMap((e) => {\n\t\t\t\t\tconst target = contents.find((c) => c.id === e.targetContentId);\n\t\t\t\t\tconst inForce = target?.inForce?.releaseId ?? \"\";\n\t\t\t\t\tif (inForce === e.pinReleaseId) return [];\n\t\t\t\t\treturn [{ edge: { ...e }, supersededByReleaseId: inForce, inForceReleaseId: inForce }];\n\t\t\t\t});\n\t\t},\n\n\t\tasync setContentCollections({ contentId, collectionIds }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tconst unique = [...new Set(collectionIds)];\n\t\t\tif (unique.length > 100) throw new InvalidInputError(\"at most 100 Collections\");\n\t\t\tfor (const id of unique) {\n\t\t\t\tif (!collections.some((col) => col.id === id)) throw notFound(\"Collection\", id);\n\t\t\t}\n\t\t\tc.collectionIds = unique.sort();\n\t\t\treturn [...c.collectionIds];\n\t\t},\n\t\tasync setContentAssignees({ contentId, assigneeIds }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (new Set(assigneeIds).size !== assigneeIds.length) {\n\t\t\t\tthrow new InvalidInputError(\"each assignee is given once\");\n\t\t\t}\n\t\t\tif (assigneeIds.length > 50) throw new InvalidInputError(\"at most 50 assignees\");\n\t\t\tc.assigneeIds = [...assigneeIds];\n\t\t\treturn attributesOf(c);\n\t\t},\n\t\tasync blockContent({ contentId, blockReasonId, allowedUserIds }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (!reasons.some((r) => r.id === blockReasonId)) {\n\t\t\t\tthrow notFound(\"Block Reason\", blockReasonId);\n\t\t\t}\n\t\t\tif (new Set(allowedUserIds).size !== allowedUserIds.length) {\n\t\t\t\tthrow new InvalidInputError(\"each allowed user is given once\");\n\t\t\t}\n\t\t\tc.block = {\n\t\t\t\tblockReasonId,\n\t\t\t\tallowedUserIds: [...allowedUserIds],\n\t\t\t\tblockedBy: userId,\n\t\t\t\tblockTime: now(),\n\t\t\t};\n\t\t\treturn attributesOf(c);\n\t\t},\n\t\tasync unblockContent(contentId) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tc.block = undefined;\n\t\t\treturn attributesOf(c);\n\t\t},\n\t\tasync archiveContent(contentId) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (c.archiveTime) return attributesOf(c);\n\t\t\tif (!c.main) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`Content ${contentId} is not published: discard its Change Set instead of archiving it`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (inForceOnOrAfter(c.timeline ?? [], today())) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`Content ${contentId} has a Release In Force today or later: end its force first`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tc.archiveTime = now();\n\t\t\treturn attributesOf(c);\n\t\t},\n\t\tasync unarchiveContent(contentId) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tc.archiveTime = undefined;\n\t\t\treturn attributesOf(c);\n\t\t},\n\n\t\tasync openDirectEdit({ contentId, idempotencyKey }) {\n\t\t\treturn once(idempotencyKey, [\"openDirectEdit\", contentId], async () => {\n\t\t\t\tconst c = findContent(contentId);\n\t\t\t\tconst mine = changeSets.find(\n\t\t\t\t\t(cs) =>\n\t\t\t\t\t\tcs.kind === \"direct_edit\" &&\n\t\t\t\t\t\tcs.state === \"open\" &&\n\t\t\t\t\t\tcs.editorId === userId &&\n\t\t\t\t\t\tcs.chains[0]?.contentId === contentId,\n\t\t\t\t);\n\t\t\t\tif (mine) {\n\t\t\t\t\tconst [content] = readsOf(c, { kind: \"change_set\", changeSetId: mine.id }, \"\");\n\t\t\t\t\treturn { changeSet: copy(mine), content, reopened: true };\n\t\t\t\t}\n\t\t\t\tif (c.main && datedContent(c)) {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"dated_content\",\n\t\t\t\t\t\t`Content ${contentId} is Dated: change it in a Change Set`,\n\t\t\t\t\t\tcontentId,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// The stub's Content names its Blueprint by id where a Release\n\t\t\t\t// names no accessor, as its Required Checks do.\n\t\t\t\tconst accessor = resolved[c.blueprintReleaseId]?.accessor || c.blueprintId;\n\t\t\t\tconst mode = effectiveOf(\n\t\t\t\t\teditingOverrides.find((o) => o.blueprintAccessor === accessor),\n\t\t\t\t).editingMode;\n\t\t\t\tif (c.main && mode === \"change_sets\") {\n\t\t\t\t\tthrow new EditingModeRefusedError(contentId, accessor, mode);\n\t\t\t\t}\n\t\t\t\tconst started = await client.startEditing({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tchangeSetName: `Direct Edit of ${contentId}`,\n\t\t\t\t});\n\t\t\t\tconst cs = find(started.changeSet.id);\n\t\t\t\tcs.kind = \"direct_edit\";\n\t\t\t\tcs.editorId = userId;\n\t\t\t\treturn { changeSet: copy(cs), content: started.content, reopened: false };\n\t\t\t});\n\t\t},\n\t\tasync publishDirectEdit({ id, expectedHeadId, idempotencyKey }) {\n\t\t\treturn once(idempotencyKey, [\"publishDirectEdit\", id, expectedHeadId], async () => {\n\t\t\t\tconst cs = find(id);\n\t\t\t\tif (cs.kind !== \"direct_edit\") {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"not_a_direct_edit\",\n\t\t\t\t\t\t`Change Set ${id} is not a Direct Edit`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst chain = cs.chains[0];\n\t\t\t\tconst branch = chain?.branches[0];\n\t\t\t\tif (!chain || !branch) throw new Error(`Direct Edit ${id} has no Branch`);\n\t\t\t\tif (cs.state === \"open\" && !cs.plannedReleases.some((p) => p.branchId === branch.id)) {\n\t\t\t\t\tawait client.planRelease({ changeSetId: id, branchId: branch.id });\n\t\t\t\t}\n\t\t\t\tconst outcome = await client.publish({\n\t\t\t\t\tid,\n\t\t\t\t\treviewedHeads: { [branch.id]: expectedHeadId },\n\t\t\t\t});\n\t\t\t\t// Main moves to the head the Release pins, which is In Force from now.\n\t\t\t\tconst c = findContent(chain.contentId);\n\t\t\t\tconst head = c.branches[id];\n\t\t\t\tconst release = outcome.releases.find((r) => r.branchId === branch.id);\n\t\t\t\tif (head && release && c.main?.revisionId !== head.revisionId) {\n\t\t\t\t\tconst { branchId: _, ...main } = structuredClone(head);\n\t\t\t\t\tc.main = main;\n\t\t\t\t\tc.inForce = { ...structuredClone(main), releaseId: release.id };\n\t\t\t\t\tc.timeline = [\n\t\t\t\t\t\t...(c.timeline ?? []),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tordinal: (c.timeline?.length ?? 0) + 1,\n\t\t\t\t\t\t\treleaseId: release.id,\n\t\t\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\t\t\trevisionId: head.revisionId,\n\t\t\t\t\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\t\t\t\t\tpublishTime: outcome.publishTime,\n\t\t\t\t\t\t\tfirst: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\treturn outcome;\n\t\t\t});\n\t\t},\n\t\tasync discardDirectEdit({ id, idempotencyKey }) {\n\t\t\treturn once(idempotencyKey, [\"discardDirectEdit\", id], async () => {\n\t\t\t\tconst cs = find(id);\n\t\t\t\tif (cs.kind !== \"direct_edit\") {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"not_a_direct_edit\",\n\t\t\t\t\t\t`Change Set ${id} is not a Direct Edit`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn client.discardChangeSet(id);\n\t\t\t});\n\t\t},\n\t\tasync startEditing({ contentId, changeSetId, effectiveOn = \"\", changeSetName = \"\" }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (!c.main) {\n\t\t\t\tthrow new InvalidInputError(`Content ${contentId} is not published`);\n\t\t\t}\n\t\t\tcheckEditable(c);\n\t\t\tif (datedContent(c) && !DAY.test(effectiveOn)) {\n\t\t\t\tthrow new InvalidInputError(\"effective_on is required for Dated Content, as YYYY-MM-DD\");\n\t\t\t}\n\t\t\tif (!datedContent(c) && effectiveOn !== \"\") {\n\t\t\t\tthrow new InvalidInputError(\"effective_on is refused for undated Content\");\n\t\t\t}\n\t\t\tlet cs: ChangeSet;\n\t\t\tif (changeSetId) {\n\t\t\t\tcs = open(changeSetId);\n\t\t\t\tif (cs.kind === \"direct_edit\") {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"one_branch\",\n\t\t\t\t\t\t`Change Set ${changeSetId} is a Direct Edit`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (cs.chains.some((chain) => chain.contentId === contentId)) {\n\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t`Content ${contentId} already has a Chain in this Change Set`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst label = Object.values(c.main.data)\n\t\t\t\t\t.filter((v): v is string => typeof v === \"string\")\n\t\t\t\t\t.slice(0, 2)\n\t\t\t\t\t.join(\" \");\n\t\t\t\tcs = {\n\t\t\t\t\tid: `cs_stub_${next++}`,\n\t\t\t\t\tname: changeSetName.trim()\n\t\t\t\t\t\t? oneLine(changeSetName, \"change_set_name\", CHANGE_SET_NAME_MAX)\n\t\t\t\t\t\t: label || contentId,\n\t\t\t\t\tstate: \"open\",\n\t\t\t\t\tcreatedBy: userId,\n\t\t\t\t\tcreateTime: now(),\n\t\t\t\t\tchains: [],\n\t\t\t\t\tdependsOnChangeSetIds: [],\n\t\t\t\t\tstatus: \"\",\n\t\t\t\t\tassigneeIds: [],\n\t\t\t\t\tplannedReleases: [],\n\t\t\t\t};\n\t\t\t\tchangeSets.unshift(cs);\n\t\t\t}\n\t\t\tconst n = next++;\n\t\t\tconst branchId = `br_stub_${n}`;\n\t\t\t// A Branch started on an existing Revision writes none.\n\t\t\tconst head = { ...structuredClone(c.main), branchId };\n\t\t\tc.branches[cs.id] = head;\n\t\t\tcs.chains.push({\n\t\t\t\tid: `chain_stub_${n}`,\n\t\t\t\tcontentId,\n\t\t\t\tborn: false,\n\t\t\t\tbranches: [\n\t\t\t\t\t{ id: branchId, position: 0, kind: \"editorial\", headRevisionId: head.revisionId },\n\t\t\t\t],\n\t\t\t});\n\t\t\tconst [content] = readsOf(c, { kind: \"change_set\", changeSetId: cs.id }, \"\");\n\t\t\treturn { changeSet: copy(cs), content };\n\t\t},\n\t\tasync previewChain({ changeSetId, contentId, effectiveOn, validityPeriod }) {\n\t\t\topen(changeSetId);\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (!c.main) throw new InvalidInputError(`Content ${contentId} is not published`);\n\t\t\tif (!datedContent(c)) throw new InvalidInputError(\"undated Content's Chain takes no date\");\n\t\t\tif (!DAY.test(effectiveOn)) throw new InvalidInputError(\"effective_on is YYYY-MM-DD\");\n\t\t\tconst entries = c.timeline ?? [];\n\t\t\tconst fork = entries.find(\n\t\t\t\t(e) =>\n\t\t\t\t\te.validityPeriod &&\n\t\t\t\t\te.validityPeriod.firstDay <= effectiveOn &&\n\t\t\t\t\t(e.validityPeriod.lastDay === \"\" || effectiveOn <= e.validityPeriod.lastDay),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tforkReleaseId: fork?.releaseId ?? \"\",\n\t\t\t\tcarryForwardReleaseIds: entries\n\t\t\t\t\t.filter((e) => e.validityPeriod && e.validityPeriod.firstDay > effectiveOn)\n\t\t\t\t\t.map((e) => e.releaseId),\n\t\t\t\tmergesMain: false,\n\t\t\t\tcutIntoReleaseIds: fork ? [fork.releaseId] : [],\n\t\t\t\t// Only a period with a last day covers a Release: an open end\n\t\t\t\t// ends where the next Release starts.\n\t\t\t\tcoveredReleaseIds:\n\t\t\t\t\tvalidityPeriod && validityPeriod.lastDay !== \"\"\n\t\t\t\t\t\t? entries\n\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t(e) =>\n\t\t\t\t\t\t\t\t\t\te.validityPeriod &&\n\t\t\t\t\t\t\t\t\t\te.validityPeriod.lastDay !== \"\" &&\n\t\t\t\t\t\t\t\t\t\tvalidityPeriod.firstDay <= e.validityPeriod.firstDay &&\n\t\t\t\t\t\t\t\t\t\te.validityPeriod.lastDay <= validityPeriod.lastDay,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.map((e) => e.releaseId)\n\t\t\t\t\t\t: [],\n\t\t\t};\n\t\t},\n\t\tasync planRepeal({ changeSetId, contentId, lastDay }) {\n\t\t\topen(changeSetId);\n\t\t\tconst c = findContent(contentId);\n\t\t\tcheckEditable(c);\n\t\t\tif (!datedContent(c)) throw new InvalidInputError(\"a Repeal is for Dated Content\");\n\t\t\tif (!DAY.test(lastDay)) throw new InvalidInputError(\"last_day is YYYY-MM-DD\");\n\t\t\tconst inForce = releaseInForceOn(c.timeline ?? [], lastDay);\n\t\t\treturn plan(c, changeSetId, {\n\t\t\t\tkind: \"repeal\",\n\t\t\t\tvalidityPeriod: { firstDay: inForce?.validityPeriod?.firstDay ?? lastDay, lastDay },\n\t\t\t});\n\t\t},\n\t\tasync planWithdrawal({ changeSetId, contentId }) {\n\t\t\topen(changeSetId);\n\t\t\tconst c = findContent(contentId);\n\t\t\tcheckEditable(c);\n\t\t\tif (datedContent(c)) throw new InvalidInputError(\"a Withdrawal is for undated Content\");\n\t\t\treturn plan(c, changeSetId, { kind: \"withdrawal\" });\n\t\t},\n\n\t\tasync planRelease({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"planRelease\", request], async () => {\n\t\t\t\tconst { changeSetId, branchId, validityPeriod, releaseSpec, supersedesReleaseIds } =\n\t\t\t\t\trequest;\n\t\t\t\tconst { cs, chain, branch, c } = branchIn(changeSetId, branchId);\n\t\t\t\tcheckEditable(c);\n\t\t\t\tif (branch.kind !== \"editorial\") {\n\t\t\t\t\tthrow new InvalidInputError(\"only an editorial Branch's head is released\");\n\t\t\t\t}\n\t\t\t\tif (cs.plannedReleases.some((p) => p.branchId === branchId)) {\n\t\t\t\t\tthrow new InvalidInputError(`Branch ${branchId} is planned already`);\n\t\t\t\t}\n\t\t\t\tconst plan: PlannedRelease = {\n\t\t\t\t\tid: `rls_stub_${next++}`,\n\t\t\t\t\tcontentId: chain.contentId,\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\tbranchId,\n\t\t\t\t\trevisionId: \"\",\n\t\t\t\t\tvalidityPeriod: validityPeriod ? { ...validityPeriod } : undefined,\n\t\t\t\t\treleaseSpec: structuredClone(releaseSpec ?? {}),\n\t\t\t\t\tsupersedesReleaseIds: [...(supersedesReleaseIds ?? [])],\n\t\t\t\t\tproposed: false,\n\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\twithheld: false,\n\t\t\t\t};\n\t\t\t\tcheckPlan(c, plan);\n\t\t\t\tcs.plannedReleases.push(plan);\n\t\t\t\trepropose(cs, c);\n\t\t\t\treturn structuredClone(plan);\n\t\t\t});\n\t\t},\n\t\tasync updatePlannedRelease({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"updatePlannedRelease\", request], async () => {\n\t\t\t\tconst { changeSetId, plannedReleaseId, validityPeriod, releaseSpec, supersedesReleaseIds } =\n\t\t\t\t\trequest;\n\t\t\t\tconst cs = open(changeSetId);\n\t\t\t\tconst at = cs.plannedReleases.findIndex((p) => p.id === plannedReleaseId);\n\t\t\t\tif (at < 0) throw notFound(\"Planned Release\", plannedReleaseId);\n\t\t\t\tconst current = cs.plannedReleases[at];\n\t\t\t\tif (current.proposed) {\n\t\t\t\t\tthrow new InvalidInputError(\"a proposal is derived from the plans and can't be set\");\n\t\t\t\t}\n\t\t\t\tconst c = findContent(current.contentId);\n\t\t\t\tcheckEditable(c);\n\t\t\t\tconst updated: PlannedRelease = {\n\t\t\t\t\t...structuredClone(current),\n\t\t\t\t\t...(validityPeriod ? { validityPeriod: { ...validityPeriod } } : {}),\n\t\t\t\t\t...(releaseSpec ? { releaseSpec: structuredClone(releaseSpec) } : {}),\n\t\t\t\t\t...(supersedesReleaseIds ? { supersedesReleaseIds: [...supersedesReleaseIds] } : {}),\n\t\t\t\t};\n\t\t\t\tcheckPlan(c, updated);\n\t\t\t\tcs.plannedReleases[at] = updated;\n\t\t\t\trepropose(cs, c);\n\t\t\t\treturn structuredClone(updated);\n\t\t\t});\n\t\t},\n\t\tasync appendBranch({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"appendBranch\", request], async () => {\n\t\t\t\tconst { changeSetId, chainId, effectiveOn } = request;\n\t\t\t\tconst cs = open(changeSetId);\n\t\t\t\tconst chain = cs.chains.find((ch) => ch.id === chainId);\n\t\t\t\tif (!chain) throw notFound(\"Chain\", chainId);\n\t\t\t\tconst c = findContent(chain.contentId);\n\t\t\t\tif (chain.born || !datedContent(c)) {\n\t\t\t\t\tthrow new InvalidInputError(\"only a Chain on published Dated Content takes dates\");\n\t\t\t\t}\n\t\t\t\tconst last = chain.branches.filter((b) => b.kind === \"editorial\").at(-1);\n\t\t\t\tif (!DAY.test(effectiveOn) || (last?.effectiveOn && effectiveOn <= last.effectiveOn)) {\n\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t\"effective_on is a day after the Chain's last editorial Branch's\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst tip = chain.branches.at(-1);\n\t\t\t\tconst n = next++;\n\t\t\t\tconst branchId = `br_stub_${n}`;\n\t\t\t\tchain.branches.push({\n\t\t\t\t\tid: branchId,\n\t\t\t\t\tposition: chain.branches.length,\n\t\t\t\t\tkind: \"editorial\",\n\t\t\t\t\t// A Branch starts at the head of the one before: no Revision written.\n\t\t\t\t\theadRevisionId: tip?.headRevisionId ?? \"\",\n\t\t\t\t\teffectiveOn,\n\t\t\t\t});\n\t\t\t\tconst head = c.branches[changeSetId];\n\t\t\t\tif (head) c.branches[changeSetId] = { ...head, branchId };\n\t\t\t\treturn { changeSet: copy(cs), branchId };\n\t\t\t});\n\t\t},\n\t\tasync dropChain({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"dropChain\", request], async () => {\n\t\t\t\tconst { changeSetId, chainId } = request;\n\t\t\t\tconst cs = open(changeSetId);\n\t\t\t\tconst chain = cs.chains.find((ch) => ch.id === chainId);\n\t\t\t\tif (!chain) throw notFound(\"Chain\", chainId);\n\t\t\t\tif (chain.born) {\n\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t\"the Chain of Content born in the Change Set can't be dropped: discard the Change Set\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tfor (const b of chain.branches) dropMerge(b.id);\n\t\t\t\tcs.chains = cs.chains.filter((ch) => ch.id !== chainId);\n\t\t\t\tcs.plannedReleases = cs.plannedReleases.filter((p) => p.contentId !== chain.contentId);\n\t\t\t\tdelete findContent(chain.contentId).branches[changeSetId];\n\t\t\t\treturn copy(cs);\n\t\t\t});\n\t\t},\n\t\tasync getPendingMerge(branchId) {\n\t\t\tconst pm = stored.get(branchId);\n\t\t\treturn pm ? structuredClone(pm) : null;\n\t\t},\n\t\tasync resolveMerge({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"resolveMerge\", request], async () => {\n\t\t\t\tconst { changeSetId, branchId, expectedHeadId, resolutions } = request;\n\t\t\t\tconst { chain, branch, c } = branchIn(changeSetId, branchId);\n\t\t\t\tconst pm = stored.get(branchId);\n\t\t\t\tif (!pm) throw new InvalidInputError(`Branch ${branchId} has no Pending Merge`);\n\t\t\t\tif (branch.headRevisionId !== expectedHeadId) {\n\t\t\t\t\tthrow new StaleHeadError({\n\t\t\t\t\t\tcontentId: c.id,\n\t\t\t\t\t\tbranchId,\n\t\t\t\t\t\texpectedHeadId,\n\t\t\t\t\t\tcurrentHeadId: branch.headRevisionId,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst paths = resolutions.map((r) => r.path);\n\t\t\t\tconst listed = pm.fields.map((f) => f.path);\n\t\t\t\tif (\n\t\t\t\t\tnew Set(paths).size !== paths.length ||\n\t\t\t\t\tpaths.some((p) => !listed.includes(p)) ||\n\t\t\t\t\tlisted.some((p) => !paths.includes(p))\n\t\t\t\t) {\n\t\t\t\t\tthrow new InvalidInputError(\"decide every field the Pending Merge lists, once\");\n\t\t\t\t}\n\t\t\t\tconst data = structuredClone(pm.merged);\n\t\t\t\tfor (const r of resolutions) {\n\t\t\t\t\tconst f = pm.fields.find((each) => each.path === r.path) as MergeField;\n\t\t\t\t\tconst value = \"side\" in r ? (r.side === \"ours\" ? f.ours : f.theirs) : r.value;\n\t\t\t\t\tconst key = r.path.replace(/^\\//, \"\");\n\t\t\t\t\tif (value === undefined) delete data[key];\n\t\t\t\t\telse data[key] = structuredClone(value);\n\t\t\t\t}\n\t\t\t\tconst content = writeHead({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tchain,\n\t\t\t\t\tbranch,\n\t\t\t\t\tc,\n\t\t\t\t\tdata,\n\t\t\t\t\tcause: \"resolve\",\n\t\t\t\t\tsecondParentId: pm.theirsRevisionId,\n\t\t\t\t});\n\t\t\t\tdropMerge(branchId);\n\t\t\t\treturn content;\n\t\t\t});\n\t\t},\n\t\tasync abortMerge({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"abortMerge\", request], async () => {\n\t\t\t\tbranchIn(request.changeSetId, request.branchId);\n\t\t\t\tif (!stored.has(request.branchId)) {\n\t\t\t\t\tthrow new InvalidInputError(`Branch ${request.branchId} has no Pending Merge`);\n\t\t\t\t}\n\t\t\t\tdropMerge(request.branchId);\n\t\t\t});\n\t\t},\n\t\tasync previewInForce({ contentId, changeSetId, validOn }) {\n\t\t\tconst cs = open(changeSetId);\n\t\t\tconst c = findContent(contentId);\n\t\t\tconst day = validOn || today();\n\t\t\tconst chain = cs.chains.find((ch) => ch.contentId === contentId);\n\t\t\tconst covers = (p: PlannedRelease) =>\n\t\t\t\t!p.validityPeriod ||\n\t\t\t\t(p.validityPeriod.firstDay <= day &&\n\t\t\t\t\t(p.validityPeriod.lastDay === \"\" || day <= p.validityPeriod.lastDay));\n\t\t\t// The Change Set's own plans first, read as if published now.\n\t\t\tconst plan = cs.plannedReleases.find(\n\t\t\t\t(p) => p.contentId === contentId && p.kind !== \"repeal\" && covers(p),\n\t\t\t);\n\t\t\tif (plan) {\n\t\t\t\tconst revisionId = plan.branchId\n\t\t\t\t\t? (chain?.branches.find((b) => b.id === plan.branchId)?.headRevisionId ?? \"\")\n\t\t\t\t\t: plan.revisionId;\n\t\t\t\treturn {\n\t\t\t\t\treleaseId: plan.id,\n\t\t\t\t\trevisionId,\n\t\t\t\t\tplanned: true,\n\t\t\t\t\twithheld: false,\n\t\t\t\t\tvalidityPeriod: plan.validityPeriod ? { ...plan.validityPeriod } : undefined,\n\t\t\t\t\tdata: structuredClone(dataOf(c, revisionId) ?? {}),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst entry = releaseInForceOn(c.timeline ?? [], day);\n\t\t\tif (!entry) return null;\n\t\t\treturn {\n\t\t\t\treleaseId: entry.releaseId,\n\t\t\t\trevisionId: entry.revisionId,\n\t\t\t\tplanned: false,\n\t\t\t\twithheld: false,\n\t\t\t\tvalidityPeriod: entry.validityPeriod ? { ...entry.validityPeriod } : undefined,\n\t\t\t\tdata: structuredClone(dataOf(c, entry.revisionId) ?? {}),\n\t\t\t};\n\t\t},\n\t};\n\treturn client;\n\n\t/** Plans a Release ending a Content's force in a Change Set, warning of the gap it leaves. */\n\tfunction plan(\n\t\tc: StubContent,\n\t\tchangeSetId: string,\n\t\twhat: Pick<PlannedEnd[\"plannedRelease\"], \"kind\" | \"validityPeriod\">,\n\t): PlannedEnd {\n\t\tconst plannedRelease = {\n\t\t\tid: `rls_stub_${next++}`,\n\t\t\tcontentId: c.id,\n\t\t\tbranchId: \"\",\n\t\t\t// A Repeal or Withdrawal re-pins the Revision In Force.\n\t\t\trevisionId: c.inForce?.revisionId ?? c.main?.revisionId ?? \"\",\n\t\t\tsupersedesReleaseIds: [],\n\t\t\tproposed: false,\n\t\t\tproposedForReleaseId: \"\",\n\t\t\tsplitFromReleaseId: \"\",\n\t\t\twithheld: false,\n\t\t\t...what,\n\t\t};\n\t\tc.plannedReleases = [...(c.plannedReleases ?? []), { changeSetId, plannedRelease }];\n\t\treturn structuredClone({ plannedRelease, gapReferrers: gapReferrersOf(c.id) });\n\t}\n\n\t/**\n\t * Every row one Content gives in a view: its Main head on Main, its\n\t * Release on In Force, its head in a Change Set there. A search on Main\n\t * also reads every open Branch head, one row per head that matched, as\n\t * Editor Search does (ADR 0019).\n\t */\n\tfunction readsOf(c: StubContent, view: ContentView, search: string): Content[] {\n\t\tconst row = (\n\t\t\thead: { revisionId: string; data: Record<string, unknown>; revisionCreateTime: string },\n\t\t\tat: { changeSetId?: string; branchId?: string; releaseId?: string },\n\t\t): Content => ({\n\t\t\tid: c.id,\n\t\t\tblueprintId: c.blueprintId,\n\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\trevisionId: head.revisionId,\n\t\t\tdata: structuredClone(head.data),\n\t\t\tchangeSetId: at.changeSetId ?? \"\",\n\t\t\tbranchId: at.branchId ?? \"\",\n\t\t\trevisionCreateTime: head.revisionCreateTime,\n\t\t\treleaseId: at.releaseId ?? \"\",\n\t\t});\n\t\tif (view.kind === \"in_force\") {\n\t\t\treturn c.inForce ? [row(c.inForce, { releaseId: c.inForce.releaseId })] : [];\n\t\t}\n\t\tif (view.kind === \"change_set\") {\n\t\t\tconst head = c.branches[view.changeSetId];\n\t\t\tif (!head || (search && !matches(head.data, search))) return [];\n\t\t\treturn [row(head, { changeSetId: view.changeSetId, branchId: head.branchId })];\n\t\t}\n\t\tif (!search) return c.main ? [row(c.main, {})] : [];\n\t\tconst hits: Content[] = [];\n\t\tif (c.main && matches(c.main.data, search)) hits.push(row(c.main, {}));\n\t\tfor (const [csId, head] of Object.entries(c.branches).sort(([, a], [, b]) =>\n\t\t\ta.branchId < b.branchId ? -1 : 1,\n\t\t)) {\n\t\t\tconst inOpen = changeSets.find((cs) => cs.id === csId)?.state === \"open\";\n\t\t\tif (inOpen && matches(head.data, search)) {\n\t\t\t\thits.push(row(head, { changeSetId: csId, branchId: head.branchId }));\n\t\t\t}\n\t\t}\n\t\treturn hits;\n\t}\n}\n\n/** Editor Search's match: within one field, ignoring case, any run of whitespace for any run. */\nfunction matches(data: Record<string, unknown>, search: string): boolean {\n\tconst fold = (s: string) => s.toLocaleLowerCase().replace(/\\s+/g, \" \");\n\tconst needle = fold(search);\n\treturn Object.values(data).some((v) => typeof v === \"string\" && fold(v).includes(needle));\n}\n","// A `StatusSource` over a fixed catalogue: the port a host fills with\n// statushub (ADR 0020), stubbed so a host's tests need no statushub.\nimport type { ChangeSetStatusInfo, StatusSource } from \"../types\";\nimport { stubChangeSetStatuses } from \"./fixtures\";\n\nexport function createStubStatusSource(\n\tstatuses: ChangeSetStatusInfo[] = stubChangeSetStatuses(),\n): StatusSource {\n\treturn {\n\t\tasync listChangeSetStatuses() {\n\t\t\treturn statuses.map((s) => ({ ...s }));\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"testing.js","names":["GuardianModeRequiredError","PublishRefusedError","NameTakenError","WithheldWorkError","StaleHeadError","StaleStatusError","StatusTransitionRefusedError","EditingModeRefusedError","MAX_BLUEPRINT_IDS","ContentArchivedError","CoversReleaseError","CHECK_NOTE_MAX","CheckResultDeniedError","ChangeSetClosedError","inForceOnOrAfter","RestrictionUnavailableError","sameHeads","releaseInForceOn","DAY","AccessDeniedError","headsOf","BlockReasonNameTakenError","ContentBlockedError","InvalidInputError","DirectEditRefusedError","ContentRefusedError","STUB_WORKSPACE_ID","STUB_USER_ID","STUB_OTHER_USER_ID","STUB_NOW","stubIdentity","createHostMembers","stubBlockReasons","stubChangeSetStatuses","stubStatusTransitions","stubChangeSets","stubRequiredChecks","stubCollections","stubBlueprints","stubBlueprintReleases","stubResolvedReleases","text","accessor","paragraph","stubUndatedContent","at","stubRepealedContent","stubContents","createStubBlueprintSource","q","query","blueprints","b","ids","releases","r","blueprintId","dayBefore","d","day","shiftDay","by","oneLine","value","raw","what","max","checkedSourceOf","source","checkedBlockReasonName","name","checkedRequiredCheck","input","accessors","a","RECORDERS_WORKSPACE_MODE","WITHHELD_REFUSAL","WORKSPACE_MODE_REFUSAL","notFound","ConnectError","id","Code","copy","cs","stubBlocker","fields","createStubContenthubClient","now","options","userId","statuses","transitions","reasons","changeSets","collections","c","contents","resolved","requiredChecks","authzMode","withheld","refuseWithheld","grants","recorders","recordersOf","checkId","memberIds","admin","givenEditing","workspaceEditing","editingOverrides","effectiveOf","o","overrideOut","accessorOf","inForceGroup","g","checkedGroup","u","editingModes","adminOnly","checkResults","extraBlockers","pendingMerges","conflicts","behind","stored","wroteUnder","once","key","write","asked","request","kept","answer","publishedWith","savedUnder","next","findContent","each","attributesOf","today","datedContent","revisionsOf","listed","heads","csId","h","dataOf","revisionId","missingRequired","unset","v","f","values","checkEditable","gapReferrersOf","other","e","contentId","byName","taken","except","collectionOrder","findCollection","siblingNamed","parentId","manageable","owns","narrowable","saveOnce","chain","open","changeSetId","ch","branchId","branch","expectedHeadId","head","sent","data","saved","fieldMask","stray","k","writeHead","createTime","branchIn","storeMerge","pm","conflict","dropMerge","checkPlan","vp","plan","violations","covered","repropose","previous","p","proposals","propose","same","splitFromReleaseId","its","find","statusName","s","slug","reaches","from","to","seen","subjectsOf","pr","blueprintOf","covers","check","standingsOf","subjects","resultsOn","subject","_","standing","latest","results","stale","out","byNameThenId","blockersOf","current","reviewed","dep","state","st","x","releasesOf","restore","target","snapshot","directEditPlanOf","timeline","fork","corrects","validityPeriod","validityLastDay","dateOnlyReleases","laterWordings","link","publishDirectEditOnce","isDated","dated","planned","releaseSpec","client","answers","missing","w","wording","outcome","reviewedHead","release","main","reason","matching","size","start","rawName","checkedSource","updateMask","nextName","nextSource","expectedStatus","status","assigneeIds","dependsOnId","published","reviewedHeads","blockers","cut","idempotencyKey","releaseId","changeSetName","entry","firstDay","lastDay","override","plannedRelease","chainId","chains","conflicted","pending","merged","ref","note","requiredCheckId","recording","named","result","byAccessor","blueprintAccessor","settings","editingMode","editingBlock","forceGroup","checked","held","recorder","restricted","collection","unfiled","acknowledgeDisclosure","collectionId","grantee","level","view","search","rows","readsOf","blueprintReleaseId","copyFrom","sourceRevision","n","content","rev","isOpen","found","owner","pageSize","pageToken","_data","all","after","baseId","base","before","changes","strip","page","fromReleases","includeOpenChangeSets","fromBranches","inForce","unique","collectionIds","col","blockReasonId","allowedUserIds","effectiveOn","mine","effective","mode","started","carryForward","err","discarded","group","own","previousEditorId","label","entries","supersedesReleaseIds","plannedReleaseId","updated","last","tip","paths","resolutions","validOn","row","matches","hits","fold","needle","createStubStatusSource"],"sources":["../src/testing/fixtures.ts","../src/testing/stub-blueprint-source.ts","../src/testing/stub-client.ts","../src/testing/stub-status-source.ts"],"sourcesContent":["import { createHostMembers, type HostIdentity } from \"@knkcs/anker/host\";\nimport type {\n\tBlockReason,\n\tBlueprintInfo,\n\tBlueprintReleaseInfo,\n\tChangeSet,\n\tChangeSetStatusInfo,\n\tCollection,\n\tContentBlock,\n\tEdge,\n\tEditingBlock,\n\tPlannedRelease,\n\tRequiredCheck,\n\tResolvedBlueprintRelease,\n\tResolvedField,\n\tRevision,\n\tTimelineEntry,\n} from \"../types\";\n\nexport const STUB_WORKSPACE_ID = \"ws_stub\";\nexport const STUB_USER_ID = \"user_stub\";\n/** A second member of the stub workspace, to assign and filter by. */\nexport const STUB_OTHER_USER_ID = \"user_ben\";\nexport const STUB_NOW = \"2026-10-01T09:00:00.000Z\";\n\n/** Who is looking, for anker's `TestHost` or `<HostProvider identity>`. */\nexport function stubIdentity(): HostIdentity {\n\treturn {\n\t\tuserId: STUB_USER_ID,\n\t\tworkspaceId: STUB_WORKSPACE_ID,\n\t\tmembers: createHostMembers([\n\t\t\t{ userId: STUB_USER_ID, displayName: \"Ada Editor\", email: \"ada@example.com\" },\n\t\t\t{ userId: STUB_OTHER_USER_ID, displayName: \"Ben Reviewer\", email: \"ben@example.com\" },\n\t\t]),\n\t};\n}\n\n/** A legal publisher's Block Reasons, in the service's order (by name). */\nexport function stubBlockReasons(): BlockReason[] {\n\treturn [\n\t\t{\n\t\t\tid: \"br_author\",\n\t\t\tname: \"Being revised by the author\",\n\t\t\tcreateTime: STUB_NOW,\n\t\t\tupdateTime: STUB_NOW,\n\t\t},\n\t\t{\n\t\t\tid: \"br_embargo\",\n\t\t\tname: \"Embargoed until publication\",\n\t\t\tcreateTime: STUB_NOW,\n\t\t\tupdateTime: STUB_NOW,\n\t\t},\n\t];\n}\n\n/**\n * statushub's seed catalogue for `contenthub/change_set` (spec #56, story 9),\n * as the `StatusSource` port answers it. Colours are CSS names: statushub\n * holds whatever CSS colour an admin chose.\n */\nexport function stubChangeSetStatuses(): ChangeSetStatusInfo[] {\n\treturn [\n\t\t{ slug: \"in_progress\", name: \"In Bearbeitung\", color: \"steelblue\", isDefault: true },\n\t\t{ slug: \"in_review\", name: \"In Prüfung\", color: \"orange\" },\n\t\t{ slug: \"ready\", name: \"Bereit\", color: \"seagreen\" },\n\t\t{ slug: \"on_hold\", name: \"Zurückgestellt\", color: \"gray\" },\n\t];\n}\n\n/**\n * The moves the stub's statushub allows, from slug to slugs. Anything else is\n * refused with a reason, as statushub refuses it; a move away from an unknown\n * status is never checked (contenthub ADR 0014).\n */\nexport function stubStatusTransitions(): Record<string, string[]> {\n\treturn {\n\t\tin_progress: [\"in_review\", \"on_hold\"],\n\t\tin_review: [\"in_progress\", \"ready\", \"on_hold\"],\n\t\tready: [\"in_review\", \"on_hold\"],\n\t\ton_hold: [\"in_progress\"],\n\t};\n}\n\n/**\n * A gazette's Change Sets: one open with two Chains (§ 1 amended twice, so\n * two Branches, and a paragraph born in it), one open with nothing in it yet,\n * and one published correction. Newest first, as the service lists them.\n */\nexport function stubChangeSets(): ChangeSet[] {\n\treturn [\n\t\t{\n\t\t\tid: \"cs_bgbl_270\",\n\t\t\tname: \"BGBl. 2026 I Nr. 270\",\n\t\t\tsource: { date: \"2026-09-20\", reference: \"BGBl. 2026 I Nr. 270\" },\n\t\t\tstate: \"open\",\n\t\t\tcreatedBy: STUB_USER_ID,\n\t\t\tcreateTime: \"2026-09-30T08:00:00.000Z\",\n\t\t\tchains: [\n\t\t\t\t{\n\t\t\t\t\tid: \"chain_para_1\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tborn: false,\n\t\t\t\t\tbranches: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"br_para_1_a\",\n\t\t\t\t\t\t\tposition: 0,\n\t\t\t\t\t\t\tkind: \"editorial\",\n\t\t\t\t\t\t\theadRevisionId: \"rev_p1_a2\",\n\t\t\t\t\t\t\teffectiveOn: \"2026-07-01\",\n\t\t\t\t\t\t\tcarriedReleaseId: \"rls_p1_1\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"br_para_1_b\",\n\t\t\t\t\t\t\tposition: 1,\n\t\t\t\t\t\t\tkind: \"editorial\",\n\t\t\t\t\t\t\theadRevisionId: \"rev_p1_b1\",\n\t\t\t\t\t\t\teffectiveOn: \"2026-10-01\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"chain_para_4a\",\n\t\t\t\t\tcontentId: \"content_para_4a\",\n\t\t\t\t\tborn: true,\n\t\t\t\t\tbranches: [\n\t\t\t\t\t\t{ id: \"br_para_4a\", position: 0, kind: \"editorial\", headRevisionId: \"rev_p4a_1\" },\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t\tdependsOnChangeSetIds: [],\n\t\t\tstatus: \"in_progress\",\n\t\t\tassigneeIds: [STUB_USER_ID],\n\t\t\tplannedReleases: [\n\t\t\t\t{\n\t\t\t\t\tid: \"rls_p1_2\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\tbranchId: \"br_para_1_b\",\n\t\t\t\t\trevisionId: \"\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"2026-10-01\", lastDay: \"\" },\n\t\t\t\t\tsupersedesReleaseIds: [],\n\t\t\t\t\tproposed: false,\n\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\twithheld: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t// The cut ending § 1's Release In Force the day before the\n\t\t\t\t\t// amendment starts: proposed, never planned by hand.\n\t\t\t\t\tid: \"rls_p1_1_cut\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tkind: \"date_only\",\n\t\t\t\t\tbranchId: \"\",\n\t\t\t\t\trevisionId: \"rev_p1_main\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"2020-01-01\", lastDay: \"2026-09-30\" },\n\t\t\t\t\tsupersedesReleaseIds: [\"rls_p1_1\"],\n\t\t\t\t\tproposed: true,\n\t\t\t\t\tproposedForReleaseId: \"rls_p1_1\",\n\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\twithheld: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"rls_p4a_1\",\n\t\t\t\t\tcontentId: \"content_para_4a\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\tbranchId: \"br_para_4a\",\n\t\t\t\t\trevisionId: \"\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"2026-10-01\", lastDay: \"\" },\n\t\t\t\t\tsupersedesReleaseIds: [],\n\t\t\t\t\tproposed: false,\n\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\twithheld: false,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tid: \"cs_bgbl_255\",\n\t\t\tname: \"BGBl. 2026 I Nr. 255\",\n\t\t\tsource: { date: \"2026-09-10\", reference: \"BGBl. 2026 I Nr. 255\" },\n\t\t\tstate: \"open\",\n\t\t\tcreatedBy: STUB_OTHER_USER_ID,\n\t\t\tcreateTime: \"2026-09-25T08:00:00.000Z\",\n\t\t\tchains: [],\n\t\t\tdependsOnChangeSetIds: [],\n\t\t\tstatus: \"\",\n\t\t\tassigneeIds: [STUB_OTHER_USER_ID],\n\t\t\tplannedReleases: [],\n\t\t},\n\t\t{\n\t\t\tid: \"cs_correction_3\",\n\t\t\tname: \"Correction of § 3\",\n\t\t\tstate: \"published\",\n\t\t\tcreatedBy: STUB_USER_ID,\n\t\t\tcreateTime: \"2026-09-01T08:00:00.000Z\",\n\t\t\tcloseTime: \"2026-09-02T08:00:00.000Z\",\n\t\t\tchains: [],\n\t\t\tdependsOnChangeSetIds: [],\n\t\t\tstatus: \"ready\",\n\t\t\tassigneeIds: [],\n\t\t\tplannedReleases: [],\n\t\t},\n\t];\n}\n\n/**\n * A legal publisher's Required Checks, by name: a print round trip once per\n * Change Set, and a lawyer's review of each Branch, by someone who wrote\n * none of it. Both apply to every Blueprint.\n */\nexport function stubRequiredChecks(): RequiredCheck[] {\n\treturn [\n\t\t{\n\t\t\tid: \"rc_print\",\n\t\t\tname: \"Druckprobe\",\n\t\t\tscope: \"change_set\",\n\t\t\tblueprintAccessors: [],\n\t\t\tindependent: false,\n\t\t},\n\t\t{\n\t\t\tid: \"rc_lawyer\",\n\t\t\tname: \"Juristische Prüfung\",\n\t\t\tscope: \"branch\",\n\t\t\tblueprintAccessors: [],\n\t\t\tindependent: true,\n\t\t},\n\t];\n}\n\n/**\n * A legal publisher's Collection tree, by name as the service lists it:\n * Laws holding BGB and StGB, and Commentary beside it.\n */\nexport function stubCollections(): Collection[] {\n\treturn [\n\t\t{ id: \"col_bgb\", name: \"BGB\", parentId: \"col_laws\", restricted: false },\n\t\t{ id: \"col_commentary\", name: \"Commentary\", parentId: \"\", restricted: false },\n\t\t{ id: \"col_laws\", name: \"Laws\", parentId: \"\", restricted: false },\n\t\t{ id: \"col_stgb\", name: \"StGB\", parentId: \"col_laws\", restricted: false },\n\t];\n}\n\n/**\n * The workspace's content Blueprints, as a `BlueprintSource` answers, by\n * name. Commentary has had no Release cut yet, so contenthub's catalog\n * (the stub client's `searchBlueprints`) leaves it out.\n */\nexport function stubBlueprints(): BlueprintInfo[] {\n\treturn [\n\t\t{ id: \"bp_commentary\", name: \"Commentary\" },\n\t\t{ id: \"bp_footnote\", name: \"Footnote\" },\n\t\t{ id: \"bp_paragraph\", name: \"Paragraph\" },\n\t];\n}\n\n/** Their Releases, newest first per Blueprint. */\nexport function stubBlueprintReleases(): BlueprintReleaseInfo[] {\n\treturn [\n\t\t{\n\t\t\tid: \"bpr_paragraph_2\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tname: \"2026-10\",\n\t\t\treleaseTime: \"2026-10-01T07:00:00.000Z\",\n\t\t},\n\t\t{\n\t\t\tid: \"bpr_paragraph_1\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tname: \"2026-09\",\n\t\t\treleaseTime: \"2026-09-01T07:00:00.000Z\",\n\t\t},\n\t\t{\n\t\t\tid: \"bpr_footnote_1\",\n\t\t\tblueprintId: \"bp_footnote\",\n\t\t\tname: \"2026-08\",\n\t\t\treleaseTime: \"2026-08-01T07:00:00.000Z\",\n\t\t},\n\t];\n}\n\n/** One head of a Content: its Revision, data and when it was written. */\nexport interface StubHead {\n\trevisionId: string;\n\tdata: Record<string, unknown>;\n\t/** ISO 8601. */\n\trevisionCreateTime: string;\n}\n\n/**\n * A Content of the stub workspace, every way the screens can read it. Not a\n * service type: it is what the stub keeps to answer its reads.\n */\nexport interface StubContent {\n\tid: string;\n\tblueprintId: string;\n\tblueprintReleaseId: string;\n\t/** The Collections it is filed in, directly. */\n\tcollectionIds: string[];\n\t/** Who maintains it; none when absent. */\n\tassigneeIds?: string[];\n\t/** Its Block; absent while it is not blocked. */\n\tblock?: ContentBlock;\n\t/** Its Editing Block; absent while no open Direct Edit holds one. */\n\teditingBlock?: EditingBlock;\n\t/** When it was archived, ISO 8601; absent while it is not Archived. */\n\tarchiveTime?: string;\n\t/** Its Main head; absent while it was born in an open Change Set. */\n\tmain?: StubHead;\n\t/** The Release In Force today, and the head it pins; absent for none. */\n\tinForce?: StubHead & { releaseId: string };\n\t/** The head of its Chain's last Branch in each Change Set it is in, by Change Set id. */\n\tbranches: Record<string, StubHead & { branchId: string }>;\n\t/** Its Timeline as known now; none when absent. */\n\ttimeline?: TimelineEntry[];\n\t/** What open (or since closed) Change Sets plan for it, in the order planned. */\n\tplannedReleases?: { changeSetId: string; plannedRelease: PlannedRelease }[];\n\t/** Its Revisions, newest first, beyond what its heads imply; none when absent. */\n\trevisions?: (Revision & { data?: Record<string, unknown> })[];\n\t/** The outgoing edges of its Revisions, each naming the Revision holding it. */\n\tedges?: Edge[];\n}\n\n/**\n * The Resolved Releases contenthub holds for the fixtures' Blueprint\n * Releases, by id, as `getContent` decodes them: a paragraph has a number\n * and a heading, a footnote a text. Both are Dated.\n */\nexport function stubResolvedReleases(): Record<string, ResolvedBlueprintRelease> {\n\tconst text = (accessor: string, name: string): ResolvedField => ({\n\t\tfield_type: \"text\",\n\t\tconfig: { name, api_accessor: accessor, required: false, instructions: \"\" },\n\t\tsystem: false,\n\t});\n\tconst paragraph: ResolvedBlueprintRelease = {\n\t\tdisplayName: \"Paragraph\",\n\t\taccessor: \"paragraph\",\n\t\tdated: true,\n\t\tfields: [text(\"number\", \"Number\"), text(\"heading\", \"Heading\")],\n\t\tparts: {},\n\t};\n\treturn {\n\t\tbpr_paragraph_1: paragraph,\n\t\tbpr_paragraph_2: paragraph,\n\t\tbpr_footnote_1: {\n\t\t\tdisplayName: \"Footnote\",\n\t\t\taccessor: \"footnote\",\n\t\t\tdated: true,\n\t\t\tfields: [text(\"text\", \"Text\")],\n\t\t\tparts: {},\n\t\t},\n\t\t// Undated: what a Direct Edit takes (ADR 0022).\n\t\tbpr_note_1: {\n\t\t\tdisplayName: \"Note\",\n\t\t\taccessor: \"note\",\n\t\t\tdated: false,\n\t\t\tfields: [text(\"title\", \"Title\")],\n\t\t\tparts: {},\n\t\t},\n\t};\n}\n\n/**\n * An editorial note, undated and published, whose Blueprint `note` is what a\n * Direct Edit edits (ADR 0022, #264): Dated Content takes none yet. Not among\n * `stubContents()`, so the Library's fixtures stay as they are; pass it in\n * with `contents`, and set the stub's `editingSettings` to offer Edit.\n */\nexport function stubUndatedContent(): StubContent {\n\tconst at = \"2026-09-01T08:00:00.000Z\";\n\treturn {\n\t\tid: \"content_note_1\",\n\t\tblueprintId: \"bp_note\",\n\t\tblueprintReleaseId: \"bpr_note_1\",\n\t\tcollectionIds: [],\n\t\tmain: { revisionId: \"rev_note1_main\", data: { title: \"Hinweis\" }, revisionCreateTime: at },\n\t\tinForce: {\n\t\t\trevisionId: \"rev_note1_main\",\n\t\t\tdata: { title: \"Hinweis\" },\n\t\t\trevisionCreateTime: at,\n\t\t\treleaseId: \"rls_note1_1\",\n\t\t},\n\t\tbranches: {},\n\t\ttimeline: [\n\t\t\t{\n\t\t\t\tordinal: 1,\n\t\t\t\treleaseId: \"rls_note1_1\",\n\t\t\t\tkind: \"revision\",\n\t\t\t\trevisionId: \"rev_note1_main\",\n\t\t\t\tblueprintReleaseId: \"bpr_note_1\",\n\t\t\t\tpublishTime: at,\n\t\t\t\tfirst: true,\n\t\t\t},\n\t\t],\n\t};\n}\n\n/**\n * § 3 BGB, repealed at the end of 2001: published, filed in BGB, with\n * nothing In Force today or later, so it may be archived. Not among\n * `stubContents()`, so the Library's fixtures stay as they are; pass it in\n * with `contents` to a stub that needs it.\n */\nexport function stubRepealedContent(): StubContent {\n\tconst at = \"2001-11-01T08:00:00.000Z\";\n\tconst data = { number: \"§ 3\", heading: \"(weggefallen)\" };\n\treturn {\n\t\tid: \"content_para_3\",\n\t\tblueprintId: \"bp_paragraph\",\n\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\tcollectionIds: [\"col_bgb\"],\n\t\tmain: { revisionId: \"rev_p3_main\", data, revisionCreateTime: at },\n\t\tbranches: {},\n\t\ttimeline: [\n\t\t\t{\n\t\t\t\tordinal: 1,\n\t\t\t\treleaseId: \"rls_p3_repeal\",\n\t\t\t\tkind: \"repeal\",\n\t\t\t\trevisionId: \"rev_p3_main\",\n\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\tvalidityPeriod: { firstDay: \"1900-01-01\", lastDay: \"2001-12-31\" },\n\t\t\t\tpublishTime: at,\n\t\t\t\tfirst: true,\n\t\t\t},\n\t\t],\n\t};\n}\n\n/**\n * The Content behind the fixtures' Change Sets: § 1 BGB, amended in\n * BGBl. 2026 I Nr. 270; § 2 BGB; § 4a BGB, born in that Change Set; § 211\n * StGB; and a footnote filed nowhere, published but with no Release In Force\n * yet (dated to start next year).\n */\nexport function stubContents(): StubContent[] {\n\tconst at = \"2026-09-01T08:00:00.000Z\";\n\treturn [\n\t\t{\n\t\t\tid: \"content_fn_1\",\n\t\t\tblueprintId: \"bp_footnote\",\n\t\t\tblueprintReleaseId: \"bpr_footnote_1\",\n\t\t\tcollectionIds: [],\n\t\t\tmain: {\n\t\t\t\trevisionId: \"rev_fn1_main\",\n\t\t\t\tdata: { text: \"Fassung ab 1. Januar 2027\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tbranches: {},\n\t\t\ttimeline: [\n\t\t\t\t{\n\t\t\t\t\tordinal: 1,\n\t\t\t\t\treleaseId: \"rls_fn1_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\trevisionId: \"rev_fn1_main\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_footnote_1\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"2027-01-01\", lastDay: \"\" },\n\t\t\t\t\tpublishTime: at,\n\t\t\t\t\tfirst: true,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tid: \"content_para_1\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\tcollectionIds: [\"col_bgb\"],\n\t\t\tassigneeIds: [STUB_USER_ID, STUB_OTHER_USER_ID],\n\t\t\tmain: {\n\t\t\t\trevisionId: \"rev_p1_main\",\n\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tinForce: {\n\t\t\t\treleaseId: \"rls_p1_1\",\n\t\t\t\trevisionId: \"rev_p1_main\",\n\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tbranches: {\n\t\t\t\tcs_bgbl_270: {\n\t\t\t\t\tbranchId: \"br_para_1_b\",\n\t\t\t\t\trevisionId: \"rev_p1_b1\",\n\t\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit, Erbfähigkeit\" },\n\t\t\t\t\trevisionCreateTime: \"2026-09-30T09:00:00.000Z\",\n\t\t\t\t},\n\t\t\t},\n\t\t\ttimeline: [\n\t\t\t\t{\n\t\t\t\t\tordinal: 1,\n\t\t\t\t\treleaseId: \"rls_p1_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\trevisionId: \"rev_p1_main\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"1900-01-01\", lastDay: \"\" },\n\t\t\t\t\tpublishTime: at,\n\t\t\t\t\tfirst: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\tplannedReleases: [\n\t\t\t\t{\n\t\t\t\t\tchangeSetId: \"cs_bgbl_270\",\n\t\t\t\t\tplannedRelease: {\n\t\t\t\t\t\tid: \"rls_p1_270\",\n\t\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\t\tbranchId: \"br_para_1_b\",\n\t\t\t\t\t\tvalidityPeriod: { firstDay: \"2026-11-01\", lastDay: \"\" },\n\t\t\t\t\t\trevisionId: \"\",\n\t\t\t\t\t\tsupersedesReleaseIds: [],\n\t\t\t\t\t\tproposed: false,\n\t\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\t\twithheld: false,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\t// The amendment's two saves, then the Revision Main holds.\n\t\t\trevisions: [\n\t\t\t\t{\n\t\t\t\t\tid: \"rev_p1_b1\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tparentId: \"rev_p1_a2\",\n\t\t\t\t\tsecondParentId: \"\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tcreateTime: \"2026-09-30T09:00:00.000Z\",\n\t\t\t\t\tauthor: STUB_USER_ID,\n\t\t\t\t\tcause: \"save\",\n\t\t\t\t\tbranchId: \"br_para_1_b\",\n\t\t\t\t\tchangeSetId: \"cs_bgbl_270\",\n\t\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit, Erbfähigkeit\" },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"rev_p1_a2\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tparentId: \"rev_p1_main\",\n\t\t\t\t\tsecondParentId: \"\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tcreateTime: \"2026-09-30T08:30:00.000Z\",\n\t\t\t\t\tauthor: STUB_OTHER_USER_ID,\n\t\t\t\t\tcause: \"save\",\n\t\t\t\t\tbranchId: \"br_para_1_a\",\n\t\t\t\t\tchangeSetId: \"cs_bgbl_270\",\n\t\t\t\t\tdata: { number: \"§ 1\", heading: \"Beginn der Rechtsfähigkeit des Menschen\" },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"rev_p1_main\",\n\t\t\t\t\tcontentId: \"content_para_1\",\n\t\t\t\t\tparentId: \"\",\n\t\t\t\t\tsecondParentId: \"\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tcreateTime: at,\n\t\t\t\t\tauthor: STUB_USER_ID,\n\t\t\t\t\tcause: \"create\",\n\t\t\t\t\tbranchId: \"br_para_1_main\",\n\t\t\t\t\tchangeSetId: \"cs_correction_3\",\n\t\t\t\t},\n\t\t\t],\n\t\t\t// § 1 cites § 2 at a Release since superseded: an outdated pin.\n\t\t\tedges: [\n\t\t\t\t{\n\t\t\t\t\tsourceContentId: \"content_para_1\",\n\t\t\t\t\tsourceRevisionId: \"rev_p1_main\",\n\t\t\t\t\tpath: \"/see_also\",\n\t\t\t\t\tkind: \"reference\",\n\t\t\t\t\ttargetContentId: \"content_para_2\",\n\t\t\t\t\ttargetAssetId: \"\",\n\t\t\t\t\ttargetBlueprintReleaseId: \"\",\n\t\t\t\t\tpinReleaseId: \"rls_p2_0\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tid: \"content_para_2\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\tcollectionIds: [\"col_bgb\"],\n\t\t\tmain: {\n\t\t\t\trevisionId: \"rev_p2_main\",\n\t\t\t\tdata: { number: \"§ 2\", heading: \"Eintritt der Volljährigkeit\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tinForce: {\n\t\t\t\treleaseId: \"rls_p2_1\",\n\t\t\t\trevisionId: \"rev_p2_main\",\n\t\t\t\tdata: { number: \"§ 2\", heading: \"Eintritt der Volljährigkeit\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tbranches: {},\n\t\t\ttimeline: [\n\t\t\t\t{\n\t\t\t\t\tordinal: 1,\n\t\t\t\t\treleaseId: \"rls_p2_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\trevisionId: \"rev_p2_main\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"1975-01-01\", lastDay: \"\" },\n\t\t\t\t\tpublishTime: at,\n\t\t\t\t\tfirst: false,\n\t\t\t\t},\n\t\t\t],\n\t\t\t// § 2 refers to § 1 as it is In Force: § 1's referrer.\n\t\t\tedges: [\n\t\t\t\t{\n\t\t\t\t\tsourceContentId: \"content_para_2\",\n\t\t\t\t\tsourceRevisionId: \"rev_p2_main\",\n\t\t\t\t\tpath: \"/see_also\",\n\t\t\t\t\tkind: \"reference\",\n\t\t\t\t\ttargetContentId: \"content_para_1\",\n\t\t\t\t\ttargetAssetId: \"\",\n\t\t\t\t\ttargetBlueprintReleaseId: \"\",\n\t\t\t\t\tpinReleaseId: \"\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tid: \"content_para_4a\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tblueprintReleaseId: \"bpr_paragraph_2\",\n\t\t\tcollectionIds: [\"col_bgb\"],\n\t\t\tbranches: {\n\t\t\t\tcs_bgbl_270: {\n\t\t\t\t\tbranchId: \"br_para_4a\",\n\t\t\t\t\trevisionId: \"rev_p4a_1\",\n\t\t\t\t\tdata: { number: \"§ 4a\", heading: \"Elektronische Form\" },\n\t\t\t\t\trevisionCreateTime: \"2026-09-30T10:00:00.000Z\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: \"content_stgb_211\",\n\t\t\tblueprintId: \"bp_paragraph\",\n\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\tcollectionIds: [\"col_stgb\"],\n\t\t\tassigneeIds: [STUB_OTHER_USER_ID],\n\t\t\tmain: {\n\t\t\t\trevisionId: \"rev_s211_main\",\n\t\t\t\tdata: { number: \"§ 211\", heading: \"Mord\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tinForce: {\n\t\t\t\treleaseId: \"rls_s211_1\",\n\t\t\t\trevisionId: \"rev_s211_main\",\n\t\t\t\tdata: { number: \"§ 211\", heading: \"Mord\" },\n\t\t\t\trevisionCreateTime: at,\n\t\t\t},\n\t\t\tbranches: {},\n\t\t\ttimeline: [\n\t\t\t\t{\n\t\t\t\t\tordinal: 1,\n\t\t\t\t\treleaseId: \"rls_s211_1\",\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\trevisionId: \"rev_s211_main\",\n\t\t\t\t\tblueprintReleaseId: \"bpr_paragraph_1\",\n\t\t\t\t\tvalidityPeriod: { firstDay: \"1941-09-15\", lastDay: \"\" },\n\t\t\t\t\tpublishTime: at,\n\t\t\t\t\tfirst: true,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t];\n}\n","// A `BlueprintSource` over fixed Blueprints and Releases, for a test that\n// overrides where the screens read Blueprints. Without one they read the\n// client's own catalog (#238), which the stub client serves too.\nimport type { BlueprintInfo, BlueprintReleaseInfo, BlueprintSource } from \"../types\";\nimport { stubBlueprintReleases, stubBlueprints } from \"./fixtures\";\n\nexport function createStubBlueprintSource(\n\tblueprints: BlueprintInfo[] = stubBlueprints(),\n\treleases: BlueprintReleaseInfo[] = stubBlueprintReleases(),\n): BlueprintSource {\n\treturn {\n\t\tasync searchBlueprints({ query }) {\n\t\t\tconst q = query.trim().toLocaleLowerCase();\n\t\t\treturn {\n\t\t\t\tblueprints: blueprints\n\t\t\t\t\t.filter((b) => b.name.toLocaleLowerCase().includes(q))\n\t\t\t\t\t.map((b) => ({ ...b })),\n\t\t\t\tnextPageToken: \"\",\n\t\t\t};\n\t\t},\n\t\tasync getBlueprints(ids) {\n\t\t\treturn blueprints.filter((b) => ids.includes(b.id)).map((b) => ({ ...b }));\n\t\t},\n\t\tasync listReleases(blueprintId) {\n\t\t\treturn releases.filter((r) => r.blueprintId === blueprintId).map((r) => ({ ...r }));\n\t\t},\n\t};\n}\n","// A `ContenthubClient` over an in-memory workspace seeded from the fixtures.\n//\n// It keeps state and applies the service's rules (internal/workspaceconfig,\n// internal/changesets), rather than answering every read with the same\n// fixture, so a screen's writes show up in its next read, and a refusal comes\n// back the way contenthub refuses it.\n//\n// Typed as the whole interface, so a method added to `ContenthubClient`\n// without an answer here fails this package's typecheck, not a host's test.\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport {\n\tAccessDeniedError,\n\tBLOCK_REASON_NAME_MAX,\n\tBLUEPRINT_ACCESSOR_MAX,\n\tBlockReasonNameTakenError,\n\tCHANGE_SET_NAME_MAX,\n\tCHECK_NOTE_MAX,\n\tChangeSetClosedError,\n\tCheckResultDeniedError,\n\tCOLLECTION_NAME_MAX,\n\tCONTENT_SEARCH_MAX,\n\tContentArchivedError,\n\tContentBlockedError,\n\ttype ContenthubClient,\n\tContentRefusedError,\n\tCoversReleaseError,\n\tDirectEditRefusedError,\n\tEditingModeRefusedError,\n\tGuardianModeRequiredError,\n\tInvalidInputError,\n\tMAX_BLUEPRINT_IDS,\n\tNameTakenError,\n\tPublishRefusedError,\n\tREQUIRED_CHECK_NAME_MAX,\n\tRestrictionUnavailableError,\n\tSOURCE_REFERENCE_MAX,\n\tStaleHeadError,\n\tStaleStatusError,\n\tStatusTransitionRefusedError,\n\tWithheldWorkError,\n} from \"../client/contenthub-client\";\nimport { headsOf, sameHeads } from \"../common/heads\";\nimport { DAY, inForceOnOrAfter, releaseInForceOn } from \"../common/in-force\";\nimport type {\n\tBlockReason,\n\tBlueprintInfo,\n\tBlueprintReleaseInfo,\n\tCarryForwardAnswer,\n\tChangeSet,\n\tChangeSetStatusInfo,\n\tCheckResult,\n\tCheckStanding,\n\tCollection,\n\tCollectionGrant,\n\tContent,\n\tContentAttributes,\n\tContentView,\n\tDirectEditPublishPreview,\n\tEdge,\n\tEditingMode,\n\tEditingSettings,\n\tFieldChange,\n\tMergeField,\n\tPendingMerge,\n\tPendingMergeRef,\n\tPlannedEnd,\n\tPlannedRelease,\n\tPublishBlocker,\n\tPublishOutcome,\n\tReferrer,\n\tReferrerList,\n\tRelease,\n\tRequiredCheck,\n\tRequiredCheckInput,\n\tRequiredCheckRecorders,\n\tResolvedBlueprintRelease,\n\tResolvedField,\n\tRevision,\n\tTimelineEntry,\n\tValidityPeriod,\n} from \"../types\";\n\n/** What a Direct Edit's Publish of Dated Content decides besides its values (#270). */\ninterface DatedPublish {\n\tvalidityLastDay?: string;\n\tcarryForward?: CarryForwardAnswer[];\n}\n\n/** The day before a YYYY-MM-DD day. */\nfunction dayBefore(day: string): string {\n\tconst d = new Date(`${day}T00:00:00Z`);\n\td.setUTCDate(d.getUTCDate() - 1);\n\treturn d.toISOString().slice(0, 10);\n}\n\nimport {\n\tSTUB_NOW,\n\tSTUB_OTHER_USER_ID,\n\tSTUB_USER_ID,\n\ttype StubContent,\n\tstubBlockReasons,\n\tstubBlueprintReleases,\n\tstubBlueprints,\n\tstubChangeSetStatuses,\n\tstubChangeSets,\n\tstubCollections,\n\tstubContents,\n\tstubRequiredChecks,\n\tstubResolvedReleases,\n\tstubStatusTransitions,\n} from \"./fixtures\";\n\ntype SaveInput = Omit<Parameters<ContenthubClient[\"saveRevision\"]>[0], \"idempotencyKey\">;\n\nexport interface StubContenthubClientOptions {\n\t/** The workspace's Block Reasons to start from; the fixtures' by default. */\n\tblockReasons?: BlockReason[];\n\t/** The workspace's Change Sets to start from, newest first; the fixtures' by default. */\n\tchangeSets?: ChangeSet[];\n\t/**\n\t * statushub's `contenthub/change_set` catalogue the stub checks status\n\t * moves against; the fixtures' by default.\n\t */\n\tstatuses?: ChangeSetStatusInfo[];\n\t/** The moves statushub allows, from slug to slugs; the fixtures' by default. */\n\tstatusTransitions?: Record<string, string[]>;\n\t/** The workspace's Collections, by name; the fixtures' by default. */\n\tcollections?: Collection[];\n\t/** The workspace's Content, every way it can be read; the fixtures' by default. */\n\tcontents?: StubContent[];\n\t/**\n\t * The workspace's content Blueprints, as `getBlueprints` names them;\n\t * the fixtures' by default. `searchBlueprints` lists those Content can\n\t * be made from: not `archived`, with a Release.\n\t */\n\tblueprints?: (BlueprintInfo & { archived?: boolean })[];\n\t/**\n\t * The Blueprint Releases, newest first per Blueprint, as\n\t * `listBlueprintReleases` lists them; the fixtures' by default.\n\t * `createContent` pins one without `refusals` and refuses the rest, as\n\t * contenthub refuses a Release it can't load.\n\t */\n\tblueprintReleases?: (Pick<BlueprintReleaseInfo, \"id\" | \"blueprintId\"> &\n\t\tPartial<BlueprintReleaseInfo>)[];\n\t/** The Resolved Releases `getContent` answers with, by Blueprint Release id; the fixtures' by default. */\n\tresolvedReleases?: Record<string, ResolvedBlueprintRelease>;\n\t/**\n\t * The workspace's Required Checks; the fixtures' by default. The stub\n\t * reads `blueprintAccessors` as Blueprint ids, the one name its Content\n\t * carries.\n\t */\n\trequiredChecks?: RequiredCheck[];\n\t/** Check Results recorded before, in the order they were recorded. */\n\tcheckResults?: (CheckResult & { changeSetId: string })[];\n\t/**\n\t * Blockers the stub can't derive itself (versionkit's and the Content\n\t * Graph's, such as covers_release or dangling_pin), by Change Set id:\n\t * `validatePublish` and `publish` report them beside the ones it does\n\t * derive (moved_head, the dependencies', outstanding_check).\n\t */\n\tpublishBlockers?: Record<string, PublishBlocker[]>;\n\t/**\n\t * The Branches behind their base, by id, as a Change Set published past\n\t * them leaves them (#268): `validatePublish` and `publish` report\n\t * behind_base for each until `updateFromMain` merges it or a resolution\n\t * of its Pending Merge does. An aborted merge leaves it behind.\n\t */\n\tbehind?: string[];\n\t/** The Pending Merges `updateFromMain` leaves, by Change Set id; none by default. */\n\tpendingMerges?: Record<string, PendingMergeRef[]>;\n\t/**\n\t * What an Update from Main would meet on a Branch, by Branch id: the\n\t * fields it can't merge and the rest merged. `updateFromMain` stores it\n\t * on the Branch as a Pending Merge; `pending` stores it from the start.\n\t */\n\tconflicts?: Record<string, StubConflict>;\n\t/**\n\t * contenthub's `authz.mode`: \"guardian\" by default. In \"workspace\" every\n\t * restriction and grant is refused, as contenthub refuses them, and\n\t * opening a Restricted Collection again is still allowed.\n\t */\n\tauthzMode?: \"workspace\" | \"guardian\";\n\t/** Grants on Restricted Collections, by Collection id, the owner's included. */\n\tcollectionGrants?: Record<string, CollectionGrant[]>;\n\t/**\n\t * The Change Sets, by id, holding work the caller can't see (Restricted\n\t * Content, ADR 0017): `validatePublish`, `publish`, `discardChangeSet`\n\t * and an `updateFromMain` without `chainId` refuse them with\n\t * `WithheldWorkError`, as contenthub does.\n\t */\n\twithheld?: string[];\n\t/**\n\t * Who records each Required Check, by check id; a check not named here,\n\t * and every new one, is recorded by every member. In guardian mode\n\t * `recordCheckResult` refuses a caller who is no recorder, as contenthub\n\t * does; in workspace mode every member records, and the recorder calls\n\t * are refused.\n\t */\n\trecorders?: Record<string, RequiredCheckRecorders>;\n\t/** The workspace's members, whom a grant may name; the stub identity's two by default. */\n\tmemberIds?: string[];\n\t/**\n\t * Whether the caller is a workspace admin, who manages every Restricted\n\t * Collection's grants; true by default. Otherwise only an owner does.\n\t */\n\tadmin?: boolean;\n\t/** Who the token names: the creator of a new Change Set. STUB_USER_ID by default. */\n\tuserId?: string;\n\t/** The time every write stamps; STUB_NOW by default. */\n\tnow?: () => string;\n\t/**\n\t * The workspace's own editing settings; \"Change Sets only\" without an\n\t * Editing Block by default, as for a workspace that never set them. A\n\t * Force Group left out is the admins alone.\n\t */\n\teditingSettings?: Omit<EditingSettings, \"forceGroup\"> & { forceGroup?: string[] };\n\t/** The per-Blueprint overrides of the editing settings; none by default. */\n\teditingOverrides?: StubEditingOverride[];\n}\n\n/** One stored override: a null field follows the workspace's. */\nexport interface StubEditingOverride {\n\tblueprintAccessor: string;\n\teditingMode: EditingMode | null;\n\teditingBlock: boolean | null;\n\t/** The people beside the admins; null follows the workspace's. Absent is null. */\n\tforceGroup?: string[] | null;\n}\n\n/** A merge an Update from Main would stop on (see `conflicts`). */\nexport interface StubConflict {\n\ttheirsRevisionId: string;\n\tfields: MergeField[];\n\t/** Every field but `fields`, merged. */\n\tmerged: Record<string, unknown>;\n\treason?: \"conflict\" | \"invalid\";\n\t/** Already stored on the Branch, as an earlier Update from Main left it. */\n\tpending?: boolean;\n}\n\n/** The day after (1) or before (-1) a YYYY-MM-DD day. */\nfunction shiftDay(day: string, by: 1 | -1): string {\n\tconst d = new Date(`${day}T00:00:00Z`);\n\td.setUTCDate(d.getUTCDate() + by);\n\treturn d.toISOString().slice(0, 10);\n}\n\n/** The service's rule for a name: trimmed, not blank, at most `max` characters, one line. */\nfunction oneLine(raw: string, what: string, max: number): string {\n\tconst value = raw.trim();\n\tif (value === \"\") throw new InvalidInputError(`${what} is required`);\n\tif ([...value].length > max) {\n\t\tthrow new InvalidInputError(`${what} is at most ${max} characters`);\n\t}\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\tif (/[\\u0000-\\u001f\\u007f]/.test(value)) {\n\t\tthrow new InvalidInputError(`${what} is one line of text`);\n\t}\n\treturn value;\n}\n\n/** The service's rule for a Source: a YYYY-MM-DD day and a one-line reference. */\nfunction checkedSourceOf(source: { date: string; reference: string }): {\n\tdate: string;\n\treference: string;\n} {\n\tif (!/^\\d{4}-\\d{2}-\\d{2}$/.test(source.date.trim())) {\n\t\tthrow new InvalidInputError(`source.date \"${source.date}\" is not a day as YYYY-MM-DD`);\n\t}\n\treturn {\n\t\tdate: source.date.trim(),\n\t\treference: oneLine(source.reference, \"source.reference\", SOURCE_REFERENCE_MAX),\n\t};\n}\n\nfunction checkedBlockReasonName(raw: string): string {\n\tconst name = raw.trim();\n\tif (name === \"\") throw new InvalidInputError(\"a Block Reason needs a name\");\n\tif ([...name].length > BLOCK_REASON_NAME_MAX) {\n\t\tthrow new InvalidInputError(\n\t\t\t`a Block Reason's name is at most ${BLOCK_REASON_NAME_MAX} characters`,\n\t\t);\n\t}\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\tif (/[\\u0000-\\u001f\\u007f]/.test(name)) {\n\t\tthrow new InvalidInputError(\"a Block Reason's name is one line of text\");\n\t}\n\treturn name;\n}\n\n/** The service's rule for a Required Check (internal/workspaceconfig.checkRequiredCheck). */\nfunction checkedRequiredCheck(input: RequiredCheckInput): RequiredCheckInput {\n\tconst name = oneLine(input.name, \"a Required Check's name\", REQUIRED_CHECK_NAME_MAX);\n\tif (input.scope !== \"branch\" && input.scope !== \"change_set\") {\n\t\tthrow new InvalidInputError(\"a Required Check's scope is Branch or Change Set\");\n\t}\n\tconst accessors = input.blueprintAccessors.map((raw) => {\n\t\tconst a = raw.trim();\n\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\t\tif (a === \"\" || [...a].length > BLUEPRINT_ACCESSOR_MAX || /[\\u0000-\\u001f\\u007f]/.test(a)) {\n\t\t\tthrow new InvalidInputError(`\"${a}\" is not a Blueprint accessor`);\n\t\t}\n\t\treturn a;\n\t});\n\treturn {\n\t\tname,\n\t\tscope: input.scope,\n\t\tblueprintAccessors: [...new Set(accessors)].sort(),\n\t\tindependent: input.independent,\n\t};\n}\n\n/** What contenthub answers to every recorder call in `authz.mode: workspace`. */\nconst RECORDERS_WORKSPACE_MODE =\n\t\"who records a Required Check can be narrowed only in authz.mode guardian: \" +\n\t\"in workspace mode every member records every check (ADR 0017)\";\n\n/** What contenthub answers to every whole-Change-Set write over withheld work. */\nconst WITHHELD_REFUSAL =\n\t\"this Change Set holds work you can't see: publishing, discarding or updating all of it \" +\n\t\"needs you to see every Content in it\";\n\n/** What contenthub answers to every restriction in `authz.mode: workspace`. */\nconst WORKSPACE_MODE_REFUSAL =\n\t\"Restricted Collections need authz.mode guardian: in workspace mode a restriction \" +\n\t\"could not be enforced (ADR 0017)\";\n\nfunction notFound(what: string, id: string): ConnectError {\n\treturn new ConnectError(`${what} ${id}: not found`, Code.NotFound);\n}\n\nconst copy = (cs: ChangeSet): ChangeSet => structuredClone(cs);\n\n/** A blocker naming only what `fields` sets; every other id \"\", as on the wire. */\nexport function stubBlocker(code: string, fields: Partial<PublishBlocker> = {}): PublishBlocker {\n\treturn {\n\t\tcode,\n\t\tcontentId: \"\",\n\t\tbranchId: \"\",\n\t\texpectedHeadId: \"\",\n\t\tcurrentHeadId: \"\",\n\t\treleaseId: \"\",\n\t\toverlapsReleaseId: \"\",\n\t\tdependencyChangeSetId: \"\",\n\t\tpath: \"\",\n\t\ttargetContentId: \"\",\n\t\tassetId: \"\",\n\t\tparentContentIds: [],\n\t\trequiredCheckId: \"\",\n\t\tcoveredReleaseId: \"\",\n\t\trevisionId: \"\",\n\t\t...fields,\n\t};\n}\n\nexport function createStubContenthubClient(\n\toptions: StubContenthubClientOptions = {},\n): ContenthubClient {\n\tconst now = options.now ?? (() => STUB_NOW);\n\tconst userId = options.userId ?? STUB_USER_ID;\n\tconst statuses = options.statuses ?? stubChangeSetStatuses();\n\tconst transitions = options.statusTransitions ?? stubStatusTransitions();\n\tlet reasons = (options.blockReasons ?? stubBlockReasons()).map((r) => ({ ...r }));\n\t// Newest first, the order the service lists them in.\n\tconst changeSets = (options.changeSets ?? stubChangeSets()).map(copy);\n\tconst collections = (options.collections ?? stubCollections()).map((c) => ({ ...c }));\n\tconst contents = structuredClone(options.contents ?? stubContents());\n\tconst blueprints: (BlueprintInfo & { archived?: boolean })[] =\n\t\toptions.blueprints ?? stubBlueprints();\n\tconst releases = options.blueprintReleases ?? stubBlueprintReleases();\n\tconst resolved = options.resolvedReleases ?? stubResolvedReleases();\n\tlet requiredChecks = structuredClone(options.requiredChecks ?? stubRequiredChecks());\n\tconst authzMode = options.authzMode ?? \"guardian\";\n\tconst withheld = new Set(options.withheld ?? []);\n\t/** Refuses a write over all of Change Set `id` while it holds work the caller can't see. */\n\tconst refuseWithheld = (id: string) => {\n\t\tif (withheld.has(id)) throw new WithheldWorkError(WITHHELD_REFUSAL);\n\t};\n\tconst grants = new Map<string, CollectionGrant[]>(\n\t\tObject.entries(structuredClone(options.collectionGrants ?? {})),\n\t);\n\tconst recorders = new Map<string, RequiredCheckRecorders>(\n\t\tObject.entries(structuredClone(options.recorders ?? {})),\n\t);\n\tconst recordersOf = (checkId: string): RequiredCheckRecorders =>\n\t\trecorders.get(checkId) ?? { everyMember: true, userIds: [] };\n\tconst memberIds = options.memberIds ?? [STUB_USER_ID, STUB_OTHER_USER_ID];\n\tconst admin = options.admin ?? true;\n\tconst givenEditing = options.editingSettings ?? {\n\t\teditingMode: \"change_sets\",\n\t\teditingBlock: false,\n\t};\n\tlet workspaceEditing: EditingSettings = structuredClone({\n\t\t...givenEditing,\n\t\tforceGroup: givenEditing.forceGroup ?? [],\n\t});\n\tlet editingOverrides = structuredClone(options.editingOverrides ?? []);\n\t/** An override over the workspace's settings, field by field (internal/workspaceconfig). */\n\tconst effectiveOf = (o: StubEditingOverride | undefined): EditingSettings => ({\n\t\teditingMode: o?.editingMode ?? workspaceEditing.editingMode,\n\t\teditingBlock: o?.editingBlock ?? workspaceEditing.editingBlock,\n\t\tforceGroup: [...(o?.forceGroup ?? workspaceEditing.forceGroup)],\n\t});\n\tconst overrideOut = (o: StubEditingOverride) => ({\n\t\t...structuredClone(o),\n\t\tforceGroup: o.forceGroup ?? null,\n\t\teffective: effectiveOf(o),\n\t});\n\t/** The Blueprint accessor of a Content, as the stub's editing settings name it. */\n\tconst accessorOf = (c: StubContent) => resolved[c.blueprintReleaseId]?.accessor || c.blueprintId;\n\t/** Whether the caller is in a Force Group: an admin, or named by it. */\n\tconst inForceGroup = (g: string[]) => admin || g.includes(userId);\n\t/** A Force Group's people: trimmed, sorted, without duplicates. */\n\tconst checkedGroup = (g: string[]) =>\n\t\t[...new Set(g.map((u) => oneLine(u, \"a user id\", 200)))].sort();\n\tconst editingModes: EditingMode[] = [\"direct_edits\", \"change_sets\", \"both\"];\n\tconst adminOnly = () => {\n\t\tif (!admin) throw new AccessDeniedError(\"permission denied\");\n\t};\n\tconst checkResults = structuredClone(options.checkResults ?? []);\n\tconst extraBlockers = options.publishBlockers ?? {};\n\tconst pendingMerges = options.pendingMerges ?? {};\n\tconst conflicts = structuredClone(options.conflicts ?? {});\n\t// The Branches behind their base, by id.\n\tconst behind = new Set(options.behind ?? []);\n\t// The Pending Merges stored on Branches, by Branch id.\n\tconst stored = new Map<string, PendingMerge>();\n\t// What each Idempotency Key's write asked and answered, beside the saves'.\n\tconst wroteUnder = new Map<string, { asked: string; answer: unknown }>();\n\t/**\n\t * A write under an Idempotency Key: a repeat answers the first and\n\t * writes nothing, another request under the key is refused.\n\t */\n\tconst once = async <T>(key: string | undefined, request: unknown, write: () => Promise<T>) => {\n\t\tif (!key) return write();\n\t\tconst asked = JSON.stringify(request);\n\t\tconst kept = wroteUnder.get(key);\n\t\tif (kept) {\n\t\t\tif (kept.asked !== asked) {\n\t\t\t\tthrow new InvalidInputError(`idempotency key ${key} names another request`);\n\t\t\t}\n\t\t\treturn structuredClone(kept.answer) as T;\n\t\t}\n\t\tconst answer = await write();\n\t\twroteUnder.set(key, { asked, answer: structuredClone(answer) });\n\t\treturn answer;\n\t};\n\t// The heads each published Change Set was published with, for a repeat.\n\tconst publishedWith = new Map<string, Record<string, string>>();\n\t// What each Idempotency Key's save asked and answered.\n\tconst savedUnder = new Map<string, { asked: string; content: Content }>();\n\tlet next = 1;\n\n\tconst findContent = (id: string): StubContent => {\n\t\tconst c = contents.find((each) => each.id === id);\n\t\tif (!c) throw notFound(\"Content\", id);\n\t\treturn c;\n\t};\n\tconst attributesOf = (c: StubContent): ContentAttributes =>\n\t\tstructuredClone({\n\t\t\tcollectionIds: [...c.collectionIds].sort(),\n\t\t\tassigneeIds: c.assigneeIds ?? [],\n\t\t\tblock: c.block,\n\t\t\tarchiveTime: c.archiveTime,\n\t\t\teditingBlock: c.editingBlock,\n\t\t});\n\tconst today = () => now().slice(0, 10);\n\tconst datedContent = (c: StubContent) => resolved[c.blueprintReleaseId]?.dated ?? false;\n\t// Every Revision the stub knows of a Content, newest first, with its data\n\t// where known: those the fixture lists, then each head not among them.\n\tconst revisionsOf = (c: StubContent): (Revision & { data?: Record<string, unknown> })[] => {\n\t\tconst listed = [...(c.revisions ?? [])];\n\t\tconst heads = [\n\t\t\t...Object.entries(c.branches).map(([csId, h]) => ({ ...h, changeSetId: csId })),\n\t\t\t...(c.main ? [{ ...c.main, branchId: \"\", changeSetId: \"\" }] : []),\n\t\t];\n\t\tfor (const h of heads) {\n\t\t\tif (listed.some((r) => r.id === h.revisionId)) continue;\n\t\t\tlisted.push({\n\t\t\t\tid: h.revisionId,\n\t\t\t\tcontentId: c.id,\n\t\t\t\tparentId: \"\",\n\t\t\t\tsecondParentId: \"\",\n\t\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\t\tcreateTime: h.revisionCreateTime,\n\t\t\t\tauthor: userId,\n\t\t\t\tcause: \"create\",\n\t\t\t\tbranchId: h.branchId,\n\t\t\t\tchangeSetId: h.changeSetId,\n\t\t\t\tdata: h.data,\n\t\t\t});\n\t\t}\n\t\treturn listed.sort((a, b) =>\n\t\t\ta.createTime < b.createTime ? 1 : a.createTime > b.createTime ? -1 : 0,\n\t\t);\n\t};\n\tconst dataOf = (c: StubContent, revisionId: string): Record<string, unknown> | undefined => {\n\t\tconst heads = [c.main, c.inForce, ...Object.values(c.branches)];\n\t\treturn (\n\t\t\theads.find((h) => h?.revisionId === revisionId)?.data ??\n\t\t\tc.revisions?.find((r) => r.id === revisionId)?.data\n\t\t);\n\t};\n\t/**\n\t * fieldkit's `required`, the one rule of its data contract the stub\n\t * applies: the accessors of the top-level required fields `values`\n\t * leaves Unset.\n\t */\n\tconst missingRequired = (\n\t\tfields: ResolvedField[] | undefined,\n\t\tvalues: Record<string, unknown>,\n\t): string[] => {\n\t\tconst unset = (v: unknown) =>\n\t\t\tv === undefined || v === null || v === \"\" || (Array.isArray(v) && v.length === 0);\n\t\treturn (fields ?? [])\n\t\t\t.filter((f) => f.config.required === true && unset(values[f.config.api_accessor]))\n\t\t\t.map((f) => f.config.api_accessor);\n\t};\n\tconst checkEditable = (c: StubContent) => {\n\t\tif (c.archiveTime) throw new ContentArchivedError(c.id);\n\t\tif (c.block && !c.block.allowedUserIds.includes(userId)) {\n\t\t\tthrow new ContentBlockedError(c.id, c.block.blockReasonId);\n\t\t}\n\t};\n\t/** The unpinned edges of Releases In Force pointing at `contentId`: what a Repeal leaves with a gap. */\n\tconst gapReferrersOf = (contentId: string): PlannedEnd[\"gapReferrers\"] =>\n\t\tcontents.flatMap((other) =>\n\t\t\t(other.edges ?? [])\n\t\t\t\t.filter(\n\t\t\t\t\t(e) =>\n\t\t\t\t\t\te.targetContentId === contentId &&\n\t\t\t\t\t\te.pinReleaseId === \"\" &&\n\t\t\t\t\t\tother.inForce?.revisionId === e.sourceRevisionId,\n\t\t\t\t)\n\t\t\t\t.map((e) => ({ edge: { ...e }, releaseId: other.inForce?.releaseId ?? \"\" })),\n\t\t);\n\n\t// The service orders by name, then id, compared as bytes.\n\tconst byName = (a: BlockReason, b: BlockReason) =>\n\t\ta.name < b.name ? -1 : a.name > b.name ? 1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\tconst taken = (name: string, except?: string) =>\n\t\treasons.some((r) => r.name === name && r.id !== except);\n\n\t// The service orders Collections by name, then id, compared as bytes.\n\tconst collectionOrder = (a: Collection, b: Collection) =>\n\t\ta.name < b.name ? -1 : a.name > b.name ? 1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\tconst findCollection = (id: string): Collection => {\n\t\tconst c = collections.find((each) => each.id === id);\n\t\tif (!c) throw notFound(\"Collection\", id);\n\t\treturn c;\n\t};\n\tconst siblingNamed = (parentId: string, name: string, except?: string) =>\n\t\tcollections.some((c) => c.parentId === parentId && c.name === name && c.id !== except);\n\t/** Refuses grant management the caller may not do, as the service does. */\n\tconst manageable = (id: string) => {\n\t\tif (authzMode === \"workspace\") throw new RestrictionUnavailableError(WORKSPACE_MODE_REFUSAL);\n\t\tconst c = findCollection(id);\n\t\tif (!c.restricted) {\n\t\t\tthrow new InvalidInputError(\n\t\t\t\t`Collection ${id} is open: only a Restricted Collection takes grants`,\n\t\t\t);\n\t\t}\n\t\tconst owns = (grants.get(id) ?? []).some((g) => g.userId === userId && g.level === \"owner\");\n\t\tif (!admin && !owns) {\n\t\t\tthrow new AccessDeniedError(\"only its owner or a workspace admin manages its grants\");\n\t\t}\n\t};\n\n\t/** Refuses recorder management the service would refuse, and returns the check's recorders. */\n\tconst narrowable = (checkId: string): RequiredCheckRecorders => {\n\t\tif (authzMode === \"workspace\") {\n\t\t\tthrow new GuardianModeRequiredError(\"required_check_recorders\", RECORDERS_WORKSPACE_MODE);\n\t\t}\n\t\tif (!admin) throw new AccessDeniedError(\"permission denied\");\n\t\tif (checkId === \"\") throw new InvalidInputError(\"required_check_id is required\");\n\t\tif (!requiredChecks.some((c) => c.id === checkId)) throw notFound(\"Required Check\", checkId);\n\t\treturn recordersOf(checkId);\n\t};\n\n\t/** One save, as SaveRevision applies it without an Idempotency Key. */\n\tconst saveOnce = async ({\n\t\tchangeSetId,\n\t\tbranchId,\n\t\texpectedHeadId,\n\t\tdata,\n\t\tfieldMask,\n\t}: SaveInput): Promise<Content> => {\n\t\tconst cs = open(changeSetId);\n\t\tconst chain = cs.chains.find((ch) => ch.branches.some((b) => b.id === branchId));\n\t\tconst branch = chain?.branches.find((b) => b.id === branchId);\n\t\tif (!chain || !branch) throw notFound(\"Branch\", branchId);\n\t\tconst c = findContent(chain.contentId);\n\t\tcheckEditable(c);\n\t\tif (stored.has(branchId)) {\n\t\t\tthrow new InvalidInputError(\n\t\t\t\t\"a Pending Merge waits on this Branch: resolve or abort it first\",\n\t\t\t);\n\t\t}\n\t\tif (expectedHeadId === \"\") throw new InvalidInputError(\"expected_head_id is required\");\n\t\tif (branch.headRevisionId !== expectedHeadId) {\n\t\t\tthrow new StaleHeadError({\n\t\t\t\tcontentId: c.id,\n\t\t\t\tbranchId,\n\t\t\t\texpectedHeadId,\n\t\t\t\tcurrentHeadId: branch.headRevisionId,\n\t\t\t});\n\t\t}\n\t\tconst head = dataOf(c, branch.headRevisionId) ?? {};\n\t\t// Through JSON, as the wire carries it: no `undefined` survives.\n\t\tconst sent = JSON.parse(JSON.stringify(data)) as Record<string, unknown>;\n\t\tlet saved: Record<string, unknown>;\n\t\tif (fieldMask) {\n\t\t\tconst stray = Object.keys(sent).filter((k) => !fieldMask.includes(k));\n\t\t\tif (stray.length > 0) {\n\t\t\t\tthrow new InvalidInputError(`data holds ${stray.join(\", \")}, which the mask doesn't name`);\n\t\t\t}\n\t\t\tsaved = structuredClone(head);\n\t\t\tfor (const key of fieldMask) {\n\t\t\t\tif (key in sent) saved[key] = sent[key];\n\t\t\t\telse delete saved[key];\n\t\t\t}\n\t\t} else {\n\t\t\tsaved = sent;\n\t\t}\n\t\t// No rule of fieldkit's data contract is applied: a save may leave\n\t\t// required Fields empty, and Publish asks for them (#180).\n\t\treturn writeHead({ changeSetId, chain, branch, c, data: saved, cause: \"save\" });\n\t};\n\n\t/** Writes a Revision on a Branch, on its head, which it becomes. */\n\tconst writeHead = ({\n\t\tchangeSetId,\n\t\tchain,\n\t\tbranch,\n\t\tc,\n\t\tdata,\n\t\tcause,\n\t\tsecondParentId = \"\",\n\t}: {\n\t\tchangeSetId: string;\n\t\tchain: ChangeSet[\"chains\"][number];\n\t\tbranch: ChangeSet[\"chains\"][number][\"branches\"][number];\n\t\tc: StubContent;\n\t\tdata: Record<string, unknown>;\n\t\tcause: Revision[\"cause\"];\n\t\tsecondParentId?: string;\n\t}): Content => {\n\t\tconst branchId = branch.id;\n\t\tconst n = next++;\n\t\tconst revisionId = `rev_stub_${n}`;\n\t\tconst createTime = now();\n\t\tc.revisions = [\n\t\t\t{\n\t\t\t\tid: revisionId,\n\t\t\t\tcontentId: c.id,\n\t\t\t\tparentId: branch.headRevisionId,\n\t\t\t\tsecondParentId,\n\t\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\t\tcreateTime,\n\t\t\t\tauthor: userId,\n\t\t\t\tcause,\n\t\t\t\tbranchId,\n\t\t\t\tchangeSetId,\n\t\t\t\tdata: structuredClone(data),\n\t\t\t},\n\t\t\t...(c.revisions ?? []),\n\t\t];\n\t\tbranch.headRevisionId = revisionId;\n\t\t// The Change Set read holds the head of the Chain's last Branch.\n\t\tif (chain.branches.at(-1)?.id === branchId) {\n\t\t\tc.branches[changeSetId] = {\n\t\t\t\tbranchId,\n\t\t\t\trevisionId,\n\t\t\t\tdata: structuredClone(data),\n\t\t\t\trevisionCreateTime: createTime,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tid: c.id,\n\t\t\tblueprintId: c.blueprintId,\n\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\trevisionId,\n\t\t\tdata: structuredClone(data),\n\t\t\tchangeSetId,\n\t\t\tbranchId,\n\t\t\trevisionCreateTime: createTime,\n\t\t\treleaseId: \"\",\n\t\t};\n\t};\n\n\t/** The Chain and Branch of `branchId` in an open Change Set, and its Content. */\n\tconst branchIn = (changeSetId: string, branchId: string) => {\n\t\tconst cs = open(changeSetId);\n\t\tconst chain = cs.chains.find((ch) => ch.branches.some((b) => b.id === branchId));\n\t\tconst branch = chain?.branches.find((b) => b.id === branchId);\n\t\tif (!chain || !branch) throw notFound(\"Branch\", branchId);\n\t\treturn { cs, chain, branch, c: findContent(chain.contentId) };\n\t};\n\n\t/** Stores what an Update from Main met on a Branch as its Pending Merge. */\n\tconst storeMerge = (branchId: string, conflict: StubConflict) => {\n\t\tfor (const cs of changeSets) {\n\t\t\tfor (const chain of cs.chains) {\n\t\t\t\tconst branch = chain.branches.find((b) => b.id === branchId);\n\t\t\t\tif (!branch) continue;\n\t\t\t\tconst pm: PendingMerge = {\n\t\t\t\t\tbranchId,\n\t\t\t\t\tcontentId: chain.contentId,\n\t\t\t\t\treason: conflict.reason ?? \"conflict\",\n\t\t\t\t\toursRevisionId: branch.headRevisionId,\n\t\t\t\t\ttheirsRevisionId: conflict.theirsRevisionId,\n\t\t\t\t\tcarried: false,\n\t\t\t\t\tfields: structuredClone(conflict.fields),\n\t\t\t\t\tmerged: structuredClone(conflict.merged),\n\t\t\t\t};\n\t\t\t\tstored.set(branchId, pm);\n\t\t\t\tbranch.hasPendingMerge = true;\n\t\t\t\tdelete conflicts[branchId];\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthrow notFound(\"Branch\", branchId);\n\t};\n\tconst dropMerge = (branchId: string) => {\n\t\tstored.delete(branchId);\n\t\tfor (const cs of changeSets) {\n\t\t\tfor (const chain of cs.chains) {\n\t\t\t\tconst branch = chain.branches.find((b) => b.id === branchId);\n\t\t\t\tif (branch) branch.hasPendingMerge = false;\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * A plan checked as the service checks it: a Validity Period for Dated\n\t * Content and none for undated, its Release Spec's required values, and\n\t * no Release of the Content covered entirely unless it supersedes it.\n\t */\n\tconst checkPlan = (\n\t\tc: StubContent,\n\t\tplan: Pick<PlannedRelease, \"validityPeriod\" | \"releaseSpec\" | \"supersedesReleaseIds\">,\n\t) => {\n\t\tconst vp = plan.validityPeriod;\n\t\tif (datedContent(c)) {\n\t\t\tif (!vp || !DAY.test(vp.firstDay)) {\n\t\t\t\tthrow new InvalidInputError(\"validity_period.first_day is required for Dated Content\");\n\t\t\t}\n\t\t\tif (vp.lastDay !== \"\" && (!DAY.test(vp.lastDay) || vp.lastDay < vp.firstDay)) {\n\t\t\t\tthrow new InvalidInputError(\"validity_period.last_day is a day on or after first_day\");\n\t\t\t}\n\t\t} else if (vp) {\n\t\t\tthrow new InvalidInputError(\"validity_period is refused for undated Content\");\n\t\t}\n\t\tconst violations = missingRequired(\n\t\t\tresolved[c.blueprintReleaseId]?.releaseSpec,\n\t\t\tplan.releaseSpec ?? {},\n\t\t).map((accessor) => ({ source: \"fieldkit\", code: \"required\", path: `/${accessor}` }));\n\t\tif (violations.length > 0) {\n\t\t\tthrow new ContentRefusedError(\n\t\t\t\t\"the Release Spec values break the Blueprint Release\",\n\t\t\t\tviolations,\n\t\t\t);\n\t\t}\n\t\tif (vp && vp.lastDay !== \"\") {\n\t\t\tconst covered = (c.timeline ?? [])\n\t\t\t\t.filter(\n\t\t\t\t\t(e) =>\n\t\t\t\t\t\te.validityPeriod &&\n\t\t\t\t\t\te.validityPeriod.lastDay !== \"\" &&\n\t\t\t\t\t\tvp.firstDay <= e.validityPeriod.firstDay &&\n\t\t\t\t\t\te.validityPeriod.lastDay <= vp.lastDay &&\n\t\t\t\t\t\t!plan.supersedesReleaseIds.includes(e.releaseId),\n\t\t\t\t)\n\t\t\t\t.map((e) => e.releaseId);\n\t\t\tif (covered.length > 0) throw new CoversReleaseError(c.id, covered);\n\t\t}\n\t};\n\n\t/**\n\t * The Change Set's proposals for a Content, derived again from its plans\n\t * (versionkit ADR 0003): a date-only cut of each Release a planned period\n\t * cuts into, and a tail resuming its wording after a period strictly\n\t * inside it. A proposal keeps its id while it proposes for the same Release.\n\t */\n\tconst repropose = (cs: ChangeSet, c: StubContent) => {\n\t\tconst previous = cs.plannedReleases.filter((p) => p.contentId === c.id && p.proposed);\n\t\tconst kept = cs.plannedReleases.filter((p) => !(p.contentId === c.id && p.proposed));\n\t\tconst proposals: PlannedRelease[] = [];\n\t\tconst propose = (\n\t\t\te: TimelineEntry,\n\t\t\tvalidityPeriod: { firstDay: string; lastDay: string },\n\t\t\tsplitFromReleaseId: string,\n\t\t) => {\n\t\t\tconst same = previous.find(\n\t\t\t\t(p) =>\n\t\t\t\t\tp.proposedForReleaseId === e.releaseId && p.splitFromReleaseId === splitFromReleaseId,\n\t\t\t);\n\t\t\tproposals.push({\n\t\t\t\tid: same?.id ?? `rls_stub_${next++}`,\n\t\t\t\tcontentId: c.id,\n\t\t\t\tkind: \"date_only\",\n\t\t\t\tbranchId: \"\",\n\t\t\t\trevisionId: e.revisionId,\n\t\t\t\tvalidityPeriod,\n\t\t\t\tsupersedesReleaseIds: splitFromReleaseId ? [] : [e.releaseId],\n\t\t\t\tproposed: true,\n\t\t\t\tproposedForReleaseId: e.releaseId,\n\t\t\t\tsplitFromReleaseId,\n\t\t\t\twithheld: false,\n\t\t\t});\n\t\t};\n\t\tfor (const plan of kept) {\n\t\t\tconst vp = plan.validityPeriod;\n\t\t\tif (plan.contentId !== c.id || plan.kind !== \"revision\" || !vp) continue;\n\t\t\tfor (const e of c.timeline ?? []) {\n\t\t\t\tconst its = e.validityPeriod;\n\t\t\t\tif (!its || plan.supersedesReleaseIds.includes(e.releaseId)) continue;\n\t\t\t\tif (!(its.firstDay < vp.firstDay && (its.lastDay === \"\" || its.lastDay >= vp.firstDay))) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpropose(e, { firstDay: its.firstDay, lastDay: shiftDay(vp.firstDay, -1) }, \"\");\n\t\t\t\tif (vp.lastDay !== \"\" && (its.lastDay === \"\" || its.lastDay > vp.lastDay)) {\n\t\t\t\t\tpropose(e, { firstDay: shiftDay(vp.lastDay, 1), lastDay: its.lastDay }, e.releaseId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcs.plannedReleases = [...kept, ...proposals];\n\t};\n\n\tconst find = (id: string): ChangeSet => {\n\t\tconst cs = changeSets.find((c) => c.id === id);\n\t\tif (!cs) throw notFound(\"Change Set\", id);\n\t\treturn cs;\n\t};\n\tconst open = (id: string): ChangeSet => {\n\t\tconst cs = find(id);\n\t\tif (cs.state !== \"open\") throw new ChangeSetClosedError(cs.state);\n\t\treturn cs;\n\t};\n\tconst statusName = (slug: string) => statuses.find((s) => s.slug === slug)?.name ?? slug;\n\t// Whether `from` reaches `to` through dependencies.\n\tconst reaches = (from: string, to: string, seen = new Set<string>()): boolean => {\n\t\tif (from === to) return true;\n\t\tif (seen.has(from)) return false;\n\t\tseen.add(from);\n\t\tconst cs = changeSets.find((c) => c.id === from);\n\t\treturn (cs?.dependsOnChangeSetIds ?? []).some((d) => reaches(d, to, seen));\n\t};\n\n\t// What a Required Check applies to in a Change Set, as the service's\n\t// currentView reads it: every Branch at its head, then every Branch-less\n\t// Planned Release at the Revision it re-pins.\n\tconst subjectsOf = (cs: ChangeSet) => [\n\t\t...cs.chains.flatMap((chain) =>\n\t\t\tchain.branches.map((b) => ({\n\t\t\t\tkey: b.id,\n\t\t\t\tbranchless: false,\n\t\t\t\tcontentId: chain.contentId,\n\t\t\t\trevision: b.headRevisionId,\n\t\t\t})),\n\t\t),\n\t\t...cs.plannedReleases\n\t\t\t.filter((pr) => pr.kind !== \"revision\" && pr.revisionId !== \"\")\n\t\t\t.map((pr) => ({\n\t\t\t\tkey: pr.id,\n\t\t\t\tbranchless: true,\n\t\t\t\tcontentId: pr.contentId,\n\t\t\t\trevision: pr.revisionId,\n\t\t\t})),\n\t];\n\tconst blueprintOf = (contentId: string) => contents.find((c) => c.id === contentId)?.blueprintId;\n\tconst covers = (check: RequiredCheck, contentId: string) =>\n\t\tcheck.blueprintAccessors.length === 0 ||\n\t\tcheck.blueprintAccessors.includes(blueprintOf(contentId) ?? \"\");\n\n\t/** Where each check stands, by name, as ListCheckResults answers. */\n\tconst standingsOf = (cs: ChangeSet): CheckStanding[] => {\n\t\tconst subjects = subjectsOf(cs);\n\t\t// Newest first. A Branch-scope result is about the one head it names,\n\t\t// a Change Set-scope one (\"\" here) about the whole.\n\t\tconst resultsOn = (check: RequiredCheck, subject: string): CheckResult[] =>\n\t\t\tcheckResults\n\t\t\t\t.filter((r) => r.changeSetId === cs.id && r.requiredCheckId === check.id)\n\t\t\t\t.filter((r) => (check.scope === \"change_set\" ? \"\" : Object.keys(r.heads)[0]) === subject)\n\t\t\t\t.reverse()\n\t\t\t\t.map(({ changeSetId: _, ...r }) => structuredClone(r));\n\t\tconst standing = (\n\t\t\tcheck: RequiredCheck,\n\t\t\tat: Pick<CheckStanding, \"contentId\" | \"branchId\" | \"releaseId\" | \"heads\">,\n\t\t\tresults: CheckResult[],\n\t\t): CheckStanding => {\n\t\t\tconst latest = results[0];\n\t\t\tconst stale = latest ? !sameHeads(latest.heads, at.heads) : false;\n\t\t\treturn {\n\t\t\t\tcheck: structuredClone(check),\n\t\t\t\t...at,\n\t\t\t\tresults,\n\t\t\t\tstale,\n\t\t\t\tcleared: !!latest && !stale && latest.outcome !== \"failed\",\n\t\t\t};\n\t\t};\n\t\tconst out: CheckStanding[] = [];\n\t\t// By name, then id, as the service orders them.\n\t\tconst byNameThenId = (a: RequiredCheck, b: RequiredCheck) =>\n\t\t\ta.name < b.name ? -1 : a.name > b.name ? 1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\t\tfor (const check of [...requiredChecks].sort(byNameThenId)) {\n\t\t\tconst covered = subjects.filter((s) => covers(check, s.contentId));\n\t\t\tif (check.scope === \"change_set\") {\n\t\t\t\tif (covered.length === 0) continue;\n\t\t\t\tconst heads = Object.fromEntries(subjects.map((s) => [s.key, s.revision]));\n\t\t\t\tout.push(\n\t\t\t\t\tstanding(\n\t\t\t\t\t\tcheck,\n\t\t\t\t\t\t{ contentId: \"\", branchId: \"\", releaseId: \"\", heads },\n\t\t\t\t\t\tresultsOn(check, \"\"),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const s of covered) {\n\t\t\t\tout.push(\n\t\t\t\t\tstanding(\n\t\t\t\t\t\tcheck,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontentId: s.contentId,\n\t\t\t\t\t\t\tbranchId: s.branchless ? \"\" : s.key,\n\t\t\t\t\t\t\treleaseId: s.branchless ? s.key : \"\",\n\t\t\t\t\t\t\theads: { [s.key]: s.revision },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresultsOn(check, s.key),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t};\n\n\t/**\n\t * The blockers a Publish of `cs` with `reviewed` meets: moved heads, open\n\t * or discarded dependencies, outstanding checks, top-level required\n\t * Fields a Branch head leaves empty, and what the options add for the\n\t * rest.\n\t */\n\tconst blockersOf = (cs: ChangeSet, reviewed: Record<string, string>): PublishBlocker[] => {\n\t\tconst out: PublishBlocker[] = [];\n\t\tconst current = headsOf(cs);\n\t\tfor (const chain of cs.chains) {\n\t\t\tfor (const b of chain.branches) {\n\t\t\t\tif (reviewed[b.id] !== b.headRevisionId) {\n\t\t\t\t\tout.push(\n\t\t\t\t\t\tstubBlocker(\"moved_head\", {\n\t\t\t\t\t\t\tcontentId: chain.contentId,\n\t\t\t\t\t\t\tbranchId: b.id,\n\t\t\t\t\t\t\texpectedHeadId: reviewed[b.id] ?? \"\",\n\t\t\t\t\t\t\tcurrentHeadId: b.headRevisionId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const [id, head] of Object.entries(reviewed)) {\n\t\t\tif (!(id in current)) {\n\t\t\t\tout.push(stubBlocker(\"moved_head\", { branchId: id, expectedHeadId: head }));\n\t\t\t}\n\t\t}\n\t\tfor (const chain of cs.chains) {\n\t\t\tfor (const b of chain.branches) {\n\t\t\t\tif (behind.has(b.id)) {\n\t\t\t\t\tout.push(stubBlocker(\"behind_base\", { contentId: chain.contentId, branchId: b.id }));\n\t\t\t\t}\n\t\t\t\tif (stored.has(b.id)) {\n\t\t\t\t\tout.push(stubBlocker(\"pending_merge\", { contentId: chain.contentId, branchId: b.id }));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const dep of cs.dependsOnChangeSetIds) {\n\t\t\tconst state = changeSets.find((c) => c.id === dep)?.state;\n\t\t\tif (state === \"open\") {\n\t\t\t\tout.push(stubBlocker(\"unpublished_dependency\", { dependencyChangeSetId: dep }));\n\t\t\t} else if (state === \"discarded\") {\n\t\t\t\tout.push(stubBlocker(\"discarded_dependency\", { dependencyChangeSetId: dep }));\n\t\t\t}\n\t\t}\n\t\tfor (const st of standingsOf(cs)) {\n\t\t\tif (!st.cleared) {\n\t\t\t\tout.push(\n\t\t\t\t\tstubBlocker(\"outstanding_check\", {\n\t\t\t\t\t\trequiredCheckId: st.check.id,\n\t\t\t\t\t\tcontentId: st.contentId,\n\t\t\t\t\t\tbranchId: st.branchId,\n\t\t\t\t\t\treleaseId: st.releaseId,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tfor (const chain of cs.chains) {\n\t\t\tconst c = contents.find((x) => x.id === chain.contentId);\n\t\t\tfor (const b of chain.branches) {\n\t\t\t\tconst data = c && dataOf(c, b.headRevisionId);\n\t\t\t\tif (!c || !data) continue;\n\t\t\t\tfor (const accessor of missingRequired(resolved[c.blueprintReleaseId]?.fields, data)) {\n\t\t\t\t\tout.push(\n\t\t\t\t\t\tstubBlocker(\"missing_required_field\", {\n\t\t\t\t\t\t\tcontentId: c.id,\n\t\t\t\t\t\t\trevisionId: b.headRevisionId,\n\t\t\t\t\t\t\tpath: `/${accessor}`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn [...out, ...structuredClone(extraBlockers[cs.id] ?? [])];\n\t};\n\n\t/** The Releases a Publish of `cs` cuts: every Planned Release not withheld. */\n\tconst releasesOf = (cs: ChangeSet): Release[] => {\n\t\tconst current = headsOf(cs);\n\t\treturn cs.plannedReleases\n\t\t\t.filter((pr) => !pr.withheld)\n\t\t\t.map((pr) => ({\n\t\t\t\tid: pr.id,\n\t\t\t\tcontentId: pr.contentId,\n\t\t\t\tkind: pr.kind,\n\t\t\t\tbranchId: pr.branchId,\n\t\t\t\trevisionId: pr.branchId ? (current[pr.branchId] ?? \"\") : pr.revisionId,\n\t\t\t\tfirst: !!cs.chains.find((c) => c.contentId === pr.contentId)?.born,\n\t\t\t\tsupersedesReleaseIds: [...pr.supersedesReleaseIds],\n\t\t\t\tvalidityPeriod: pr.validityPeriod ? { ...pr.validityPeriod } : undefined,\n\t\t\t}));\n\t};\n\n\tfor (const [branchId, conflict] of Object.entries(conflicts)) {\n\t\tif (conflict.pending) storeMerge(branchId, conflict);\n\t}\n\n\t/**\n\t * Puts `target` back as `snapshot` holds it: a refused write of one\n\t * transaction, rolled back. Keys the write added go too.\n\t */\n\tconst restore = <T extends object>(target: T, snapshot: T) => {\n\t\tfor (const key of Object.keys(target)) {\n\t\t\tif (!(key in snapshot)) delete (target as Record<string, unknown>)[key];\n\t\t}\n\t\tObject.assign(target, snapshot);\n\t};\n\n\t/**\n\t * What a Direct Edit of Dated Content plans (#270), as the service\n\t * decides it: on its opening day or earlier a correction of the Release\n\t * it forked from, keeping its period and superseding it; later a new\n\t * wording from its day, cutting into the Release it forked from. A\n\t * period covering another Release entirely is refused.\n\t */\n\tconst directEditPlanOf = (\n\t\tcs: ChangeSet,\n\t\tvalidityLastDay: string | undefined,\n\t): DirectEditPublishPreview & { validityPeriod: ValidityPeriod } => {\n\t\tconst chain = cs.chains[0];\n\t\tconst branch = chain?.branches[0];\n\t\tconst day = branch?.effectiveOn ?? \"\";\n\t\tif (!chain || !branch || !day) {\n\t\t\tthrow new InvalidInputError(\"the Direct Edit's Content is undated: no period to plan\");\n\t\t}\n\t\tconst c = findContent(chain.contentId);\n\t\tconst timeline = c.timeline ?? [];\n\t\tconst fork = timeline.find((e) => e.releaseId === branch.carriedReleaseId);\n\t\tconst corrects = fork?.validityPeriod && day <= cs.createTime.slice(0, 10) ? fork : undefined;\n\t\tconst validityPeriod: ValidityPeriod = corrects?.validityPeriod\n\t\t\t? { ...corrects.validityPeriod }\n\t\t\t: { firstDay: day, lastDay: \"\" };\n\t\tif (validityLastDay !== undefined) {\n\t\t\tif (\n\t\t\t\tvalidityLastDay !== \"\" &&\n\t\t\t\t(!DAY.test(validityLastDay) || validityLastDay < validityPeriod.firstDay)\n\t\t\t) {\n\t\t\t\tthrow new InvalidInputError(\"validity_last_day is YYYY-MM-DD, not before the first day\");\n\t\t\t}\n\t\t\tvalidityPeriod.lastDay = validityLastDay;\n\t\t}\n\t\tconst covered = timeline\n\t\t\t.filter(\n\t\t\t\t(e) =>\n\t\t\t\t\te.releaseId !== corrects?.releaseId &&\n\t\t\t\t\te.validityPeriod &&\n\t\t\t\t\tvalidityPeriod.lastDay !== \"\" &&\n\t\t\t\t\tvalidityPeriod.firstDay <= e.validityPeriod.firstDay &&\n\t\t\t\t\te.validityPeriod.lastDay !== \"\" &&\n\t\t\t\t\te.validityPeriod.lastDay <= validityPeriod.lastDay,\n\t\t\t)\n\t\t\t.map((e) => e.releaseId);\n\t\tif (covered.length > 0) throw new CoversReleaseError(c.id, covered, true);\n\t\tconst dateOnlyReleases: PlannedRelease[] = [];\n\t\tif (!corrects && fork?.validityPeriod && fork.validityPeriod.firstDay < day) {\n\t\t\tdateOnlyReleases.push({\n\t\t\t\tid: `rls_stub_${next++}`,\n\t\t\t\tcontentId: c.id,\n\t\t\t\tkind: \"date_only\",\n\t\t\t\tbranchId: \"\",\n\t\t\t\trevisionId: fork.revisionId,\n\t\t\t\tvalidityPeriod: { firstDay: fork.validityPeriod.firstDay, lastDay: dayBefore(day) },\n\t\t\t\tsupersedesReleaseIds: [fork.releaseId],\n\t\t\t\tproposed: true,\n\t\t\t\tproposedForReleaseId: fork.releaseId,\n\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\twithheld: false,\n\t\t\t});\n\t\t}\n\t\tconst laterWordings = chain.branches.slice(1).flatMap((link) => {\n\t\t\tconst e = timeline.find((each) => each.releaseId === link.carriedReleaseId);\n\t\t\treturn e ? [{ releaseId: e.releaseId, validityPeriod: e.validityPeriod }] : [];\n\t\t});\n\t\treturn {\n\t\t\tvalidityPeriod,\n\t\t\tcorrectsReleaseId: corrects?.releaseId ?? \"\",\n\t\t\tdateOnlyReleases,\n\t\t\tlaterWordings,\n\t\t};\n\t};\n\n\t/**\n\t * A Direct Edit's Publish, as the service decides it in one place for\n\t * Publish and Save & publish: its Release planned with `releaseSpec` (or\n\t * the planned one's values replaced, when given), then published at\n\t * `head`. The caller rolls back on a refusal.\n\t */\n\tconst publishDirectEditOnce = async (\n\t\tcs: ChangeSet,\n\t\treviewedHead: string,\n\t\treleaseSpec: Record<string, unknown> | undefined,\n\t\tdated: DatedPublish = {},\n\t): Promise<PublishOutcome> => {\n\t\tconst id = cs.id;\n\t\tconst chain = cs.chains[0];\n\t\tconst branch = chain?.branches[0];\n\t\tif (!chain || !branch) throw new Error(`Direct Edit ${id} has no Branch`);\n\t\tconst isDated = !!branch.effectiveOn;\n\t\tif (\n\t\t\t!isDated &&\n\t\t\t(dated.validityLastDay !== undefined || (dated.carryForward ?? []).length > 0)\n\t\t) {\n\t\t\tthrow new InvalidInputError(\"validity_last_day and carry_forward are for Dated Content\");\n\t\t}\n\t\tif (cs.state === \"open\") {\n\t\t\tconst plan = isDated ? directEditPlanOf(cs, dated.validityLastDay) : undefined;\n\t\t\tconst planned = cs.plannedReleases.find((p) => p.branchId === branch.id && !p.proposed);\n\t\t\tif (!planned) {\n\t\t\t\tawait client.planRelease({\n\t\t\t\t\tchangeSetId: id,\n\t\t\t\t\tbranchId: branch.id,\n\t\t\t\t\treleaseSpec,\n\t\t\t\t\tvalidityPeriod: plan?.validityPeriod,\n\t\t\t\t\tsupersedesReleaseIds: plan?.correctsReleaseId ? [plan.correctsReleaseId] : undefined,\n\t\t\t\t});\n\t\t\t} else if (releaseSpec || plan) {\n\t\t\t\tawait client.updatePlannedRelease({\n\t\t\t\t\tchangeSetId: id,\n\t\t\t\t\tplannedReleaseId: planned.id,\n\t\t\t\t\treleaseSpec,\n\t\t\t\t\tvalidityPeriod: plan?.validityPeriod,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (plan) {\n\t\t\t\t// The derived cuts, and a Release per later wording the change\n\t\t\t\t// carries into, superseding it; a wording answered no keeps\n\t\t\t\t// its Release.\n\t\t\t\tconst answers = new Map((dated.carryForward ?? []).map((a) => [a.releaseId, a.carry]));\n\t\t\t\tconst missing = plan.laterWordings.filter((w) => !answers.has(w.releaseId));\n\t\t\t\tif (missing.length > 0) {\n\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t`carry_forward has no answer for the later wordings ${missing.map((w) => w.releaseId).join(\", \")}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcs.plannedReleases.push(...plan.dateOnlyReleases);\n\t\t\t\tfor (const link of chain.branches.slice(1)) {\n\t\t\t\t\tconst wording = plan.laterWordings.find((w) => w.releaseId === link.carriedReleaseId);\n\t\t\t\t\tif (!wording || !answers.get(wording.releaseId)) continue;\n\t\t\t\t\tcs.plannedReleases.push({\n\t\t\t\t\t\tid: `rls_stub_${next++}`,\n\t\t\t\t\t\tcontentId: chain.contentId,\n\t\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\t\tbranchId: link.id,\n\t\t\t\t\t\trevisionId: \"\",\n\t\t\t\t\t\tvalidityPeriod: wording.validityPeriod,\n\t\t\t\t\t\tsupersedesReleaseIds: [wording.releaseId],\n\t\t\t\t\t\tproposed: true,\n\t\t\t\t\t\tproposedForReleaseId: wording.releaseId,\n\t\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\t\twithheld: false,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst outcome = await client.publish({\n\t\t\tid,\n\t\t\treviewedHeads: { ...headsOf(cs), [branch.id]: reviewedHead },\n\t\t});\n\t\t// Main moves to the head the Release pins, which is In Force from now.\n\t\tconst c = findContent(chain.contentId);\n\t\tif (c.editingBlock?.changeSetId === id) c.editingBlock = undefined;\n\t\tconst head = c.branches[id];\n\t\tconst release = outcome.releases.find((r) => r.branchId === branch.id);\n\t\t// Behind later wordings, Main is the last one's, as carried: the stub\n\t\t// leaves it where it is.\n\t\tconst behind = chain.branches.length > 1;\n\t\tif (head && release && !behind && c.main?.revisionId !== head.revisionId) {\n\t\t\tconst { branchId: _, ...main } = structuredClone(head);\n\t\t\tc.main = main;\n\t\t\tc.inForce = { ...structuredClone(main), releaseId: release.id };\n\t\t\tc.timeline = [\n\t\t\t\t...(c.timeline ?? []),\n\t\t\t\t{\n\t\t\t\t\tordinal: (c.timeline?.length ?? 0) + 1,\n\t\t\t\t\treleaseId: release.id,\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\trevisionId: head.revisionId,\n\t\t\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\t\t\tpublishTime: outcome.publishTime,\n\t\t\t\t\tfirst: false,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn outcome;\n\t};\n\n\tconst client: ContenthubClient = {\n\t\tasync listBlockReasons() {\n\t\t\treturn [...reasons].sort(byName).map((r) => ({ ...r }));\n\t\t},\n\t\tasync createBlockReason({ name: raw }) {\n\t\t\tconst name = checkedBlockReasonName(raw);\n\t\t\tif (taken(name)) throw new BlockReasonNameTakenError(name);\n\t\t\tconst reason = { id: `br_stub_${next++}`, name, createTime: now(), updateTime: now() };\n\t\t\treasons.push(reason);\n\t\t\treturn { ...reason };\n\t\t},\n\t\tasync renameBlockReason({ id, name: raw }) {\n\t\t\tconst name = checkedBlockReasonName(raw);\n\t\t\tconst reason = reasons.find((r) => r.id === id);\n\t\t\tif (!reason) throw notFound(\"Block Reason\", id);\n\t\t\tif (taken(name, id)) throw new BlockReasonNameTakenError(name);\n\t\t\treason.name = name;\n\t\t\treason.updateTime = now();\n\t\t\treturn { ...reason };\n\t\t},\n\t\tasync deleteBlockReason({ id }) {\n\t\t\tif (!reasons.some((r) => r.id === id)) throw notFound(\"Block Reason\", id);\n\t\t\treasons = reasons.filter((r) => r.id !== id);\n\t\t},\n\n\t\tasync listChangeSets(input = {}) {\n\t\t\tconst matching = changeSets.filter(\n\t\t\t\t(cs) =>\n\t\t\t\t\t(!input.state || cs.state === input.state) &&\n\t\t\t\t\t(!input.assigneeId || cs.assigneeIds.includes(input.assigneeId)) &&\n\t\t\t\t\t(!input.contentId || cs.chains.some((c) => c.contentId === input.contentId)) &&\n\t\t\t\t\t(!input.kind || (cs.kind ?? \"change_set\") === input.kind) &&\n\t\t\t\t\t(!input.editorId || cs.editorId === input.editorId),\n\t\t\t);\n\t\t\tconst size = Math.min(input.pageSize || 50, 200);\n\t\t\tconst start = input.pageToken ? Number(input.pageToken) : 0;\n\t\t\tconst page = matching.slice(start, start + size);\n\t\t\treturn {\n\t\t\t\t// A list carries no Chains, dependencies or Planned Releases.\n\t\t\t\tchangeSets: page.map((cs) => ({\n\t\t\t\t\t...copy(cs),\n\t\t\t\t\tchains: [],\n\t\t\t\t\tdependsOnChangeSetIds: [],\n\t\t\t\t\tplannedReleases: [],\n\t\t\t\t})),\n\t\t\t\tnextPageToken: start + size < matching.length ? String(start + size) : \"\",\n\t\t\t};\n\t\t},\n\t\tasync createChangeSet({ name: rawName, source }) {\n\t\t\tconst name = oneLine(rawName, \"name\", CHANGE_SET_NAME_MAX);\n\t\t\tconst checkedSource = source ? checkedSourceOf(source) : undefined;\n\t\t\tconst cs: ChangeSet = {\n\t\t\t\tid: `cs_stub_${next++}`,\n\t\t\t\tname,\n\t\t\t\tsource: checkedSource,\n\t\t\t\tstate: \"open\",\n\t\t\t\tcreatedBy: userId,\n\t\t\t\tcreateTime: now(),\n\t\t\t\tchains: [],\n\t\t\t\tdependsOnChangeSetIds: [],\n\t\t\t\tstatus: \"\",\n\t\t\t\tassigneeIds: [],\n\t\t\t\tplannedReleases: [],\n\t\t\t};\n\t\t\tchangeSets.unshift(cs);\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync getChangeSet(id) {\n\t\t\treturn copy(find(id));\n\t\t},\n\t\tasync updateChangeSet({ id, updateMask, name, source }) {\n\t\t\tconst cs = open(id);\n\t\t\tif (updateMask.length === 0) throw new InvalidInputError(\"update_mask is required\");\n\t\t\t// Checked whole before anything changes, as the service does.\n\t\t\tconst nextName = updateMask.includes(\"name\")\n\t\t\t\t? oneLine(name ?? \"\", \"name\", CHANGE_SET_NAME_MAX)\n\t\t\t\t: cs.name;\n\t\t\tlet nextSource = cs.source;\n\t\t\tif (updateMask.includes(\"source\")) {\n\t\t\t\tnextSource = source ? checkedSourceOf(source) : undefined;\n\t\t\t}\n\t\t\tcs.name = nextName;\n\t\t\tcs.source = nextSource;\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync setChangeSetStatus({ id, expectedStatus, status }) {\n\t\t\tconst cs = open(id);\n\t\t\tif (cs.status !== expectedStatus) throw new StaleStatusError(cs.status);\n\t\t\t// Already there: nothing to ask statushub, as the service does.\n\t\t\tif (cs.status === status) return copy(cs);\n\t\t\tif (!statuses.some((s) => s.slug === status)) {\n\t\t\t\tthrow new InvalidInputError(`status \"${status}\" is not in the workspace's catalogue`);\n\t\t\t}\n\t\t\t// A move away from an unknown status is never validated, so a Change\n\t\t\t// Set is never stuck on a deleted status (ADR 0014).\n\t\t\tconst known = statuses.some((s) => s.slug === cs.status);\n\t\t\tif (known && !(transitions[cs.status] ?? []).includes(status)) {\n\t\t\t\tthrow new StatusTransitionRefusedError({\n\t\t\t\t\tfromStatus: cs.status,\n\t\t\t\t\ttoStatus: status,\n\t\t\t\t\treason: `There is no transition from ${statusName(cs.status)} to ${statusName(status)}.`,\n\t\t\t\t\trequiresPermission: false,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcs.status = status;\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync setChangeSetAssignees({ id, assigneeIds }) {\n\t\t\tconst cs = find(id);\n\t\t\tif (new Set(assigneeIds).size !== assigneeIds.length) {\n\t\t\t\tthrow new InvalidInputError(\"each assignee is given once\");\n\t\t\t}\n\t\t\tif (assigneeIds.length > 50) throw new InvalidInputError(\"at most 50 assignees\");\n\t\t\tcs.assigneeIds = [...assigneeIds];\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync addDependency({ id, dependsOnId }) {\n\t\t\tconst cs = open(id);\n\t\t\tconst target = find(dependsOnId);\n\t\t\tif (target.state !== \"open\") {\n\t\t\t\tthrow new InvalidInputError(`Change Set ${dependsOnId} is ${target.state}`);\n\t\t\t}\n\t\t\tif (reaches(dependsOnId, id)) {\n\t\t\t\tthrow new InvalidInputError(\"the dependency would close a cycle\");\n\t\t\t}\n\t\t\tif (!cs.dependsOnChangeSetIds.includes(dependsOnId)) {\n\t\t\t\tcs.dependsOnChangeSetIds.push(dependsOnId);\n\t\t\t}\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync removeDependency({ id, dependsOnId }) {\n\t\t\tconst cs = open(id);\n\t\t\tif (!cs.dependsOnChangeSetIds.includes(dependsOnId)) {\n\t\t\t\tthrow notFound(`dependency of Change Set ${id} on`, dependsOnId);\n\t\t\t}\n\t\t\tcs.dependsOnChangeSetIds = cs.dependsOnChangeSetIds.filter((d) => d !== dependsOnId);\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync validatePublish({ id, reviewedHeads }) {\n\t\t\tconst cs = find(id);\n\t\t\trefuseWithheld(id);\n\t\t\tconst published = publishedWith.get(id);\n\t\t\t// Published with these heads: the stored outcome. With others, it is closed.\n\t\t\tif (published && sameHeads(published, reviewedHeads)) {\n\t\t\t\treturn {\n\t\t\t\t\tblockers: [],\n\t\t\t\t\treleases: releasesOf(cs),\n\t\t\t\t\tpublished: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (cs.state !== \"open\") throw new ChangeSetClosedError(cs.state);\n\t\t\treturn {\n\t\t\t\tblockers: blockersOf(cs, reviewedHeads),\n\t\t\t\treleases: releasesOf(cs),\n\t\t\t\tpublished: false,\n\t\t\t};\n\t\t},\n\t\tasync publish({ id, reviewedHeads }) {\n\t\t\tconst cs = find(id);\n\t\t\trefuseWithheld(id);\n\t\t\tconst published = publishedWith.get(id);\n\t\t\t// A repeat with the same heads returns the stored outcome.\n\t\t\tif (published && sameHeads(published, reviewedHeads)) {\n\t\t\t\treturn {\n\t\t\t\t\tchangeSet: copy(cs),\n\t\t\t\t\tpublishTime: cs.closeTime ?? now(),\n\t\t\t\t\treleases: releasesOf(cs),\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (cs.state !== \"open\") throw new ChangeSetClosedError(cs.state);\n\t\t\tconst blockers = blockersOf(cs, reviewedHeads);\n\t\t\tif (blockers.length > 0) throw new PublishRefusedError(blockers);\n\t\t\tconst cut = releasesOf(cs);\n\t\t\tcs.state = \"published\";\n\t\t\tcs.closeTime = now();\n\t\t\tpublishedWith.set(id, { ...reviewedHeads });\n\t\t\treturn { changeSet: copy(cs), publishTime: cs.closeTime, releases: cut };\n\t\t},\n\t\tasync changeValidity({ releaseId, validityPeriod, changeSetName, idempotencyKey }) {\n\t\t\treturn once(\n\t\t\t\tidempotencyKey,\n\t\t\t\t[\"changeValidity\", releaseId, validityPeriod, changeSetName],\n\t\t\t\tasync () => {\n\t\t\t\t\tconst c = contents.find((each) =>\n\t\t\t\t\t\t(each.timeline ?? []).some((e) => e.releaseId === releaseId),\n\t\t\t\t\t);\n\t\t\t\t\tif (!c) throw notFound(\"Release\", releaseId);\n\t\t\t\t\tcheckEditable(c);\n\t\t\t\t\tconst timeline = c.timeline ?? [];\n\t\t\t\t\tconst entry = timeline.find((e) => e.releaseId === releaseId);\n\t\t\t\t\tif (!entry?.validityPeriod || !datedContent(c)) {\n\t\t\t\t\t\tthrow new InvalidInputError(\"undated Releases carry no Validity Period\");\n\t\t\t\t\t}\n\t\t\t\t\tconst { firstDay, lastDay = \"\" } = validityPeriod;\n\t\t\t\t\tif (\n\t\t\t\t\t\t!DAY.test(firstDay) ||\n\t\t\t\t\t\t(lastDay !== \"\" && (!DAY.test(lastDay) || lastDay < firstDay))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t\t\"validity_period is YYYY-MM-DD, the last day not before the first\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// \"Change Sets only\" refuses it, as it refuses a Direct Edit (ADR 0022).\n\t\t\t\t\tconst accessor = resolved[c.blueprintReleaseId]?.accessor ?? \"\";\n\t\t\t\t\tconst override = editingOverrides.find((o) => o.blueprintAccessor === accessor);\n\t\t\t\t\tif (effectiveOf(override).editingMode === \"change_sets\") {\n\t\t\t\t\t\tthrow new EditingModeRefusedError(c.id, accessor);\n\t\t\t\t\t}\n\t\t\t\t\tconst covered = timeline\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(e) =>\n\t\t\t\t\t\t\t\te.releaseId !== releaseId &&\n\t\t\t\t\t\t\t\te.validityPeriod &&\n\t\t\t\t\t\t\t\tfirstDay <= e.validityPeriod.firstDay &&\n\t\t\t\t\t\t\t\t(lastDay === \"\" ||\n\t\t\t\t\t\t\t\t\t(e.validityPeriod.lastDay !== \"\" && e.validityPeriod.lastDay <= lastDay)),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.map((e) => e.releaseId);\n\t\t\t\t\tif (covered.length > 0) throw new CoversReleaseError(c.id, covered, true);\n\t\t\t\t\tconst plannedRelease = {\n\t\t\t\t\t\tid: `rls_stub_${next++}`,\n\t\t\t\t\t\tcontentId: c.id,\n\t\t\t\t\t\tkind: \"date_only\" as const,\n\t\t\t\t\t\tbranchId: \"\",\n\t\t\t\t\t\trevisionId: entry.revisionId,\n\t\t\t\t\t\tvalidityPeriod: { firstDay, lastDay },\n\t\t\t\t\t\tsupersedesReleaseIds: [releaseId],\n\t\t\t\t\t\tproposed: false,\n\t\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\t\twithheld: false,\n\t\t\t\t\t};\n\t\t\t\t\tconst cs: ChangeSet = {\n\t\t\t\t\t\tid: `cs_stub_${next++}`,\n\t\t\t\t\t\tname: changeSetName?.trim() || `Change of validity of ${c.id}`,\n\t\t\t\t\t\tstate: \"open\",\n\t\t\t\t\t\tcreatedBy: userId,\n\t\t\t\t\t\tcreateTime: now(),\n\t\t\t\t\t\tchains: [],\n\t\t\t\t\t\tdependsOnChangeSetIds: [],\n\t\t\t\t\t\tstatus: \"\",\n\t\t\t\t\t\tassigneeIds: [],\n\t\t\t\t\t\tplannedReleases: [plannedRelease],\n\t\t\t\t\t};\n\t\t\t\t\t// Refused as a whole: the Change Set is never kept.\n\t\t\t\t\tconst blockers = blockersOf(cs, {});\n\t\t\t\t\tif (blockers.length > 0) throw new PublishRefusedError(blockers);\n\t\t\t\t\tconst cut = releasesOf(cs);\n\t\t\t\t\tcs.state = \"published\";\n\t\t\t\t\tcs.closeTime = now();\n\t\t\t\t\tchangeSets.unshift(cs);\n\t\t\t\t\tpublishedWith.set(cs.id, {});\n\t\t\t\t\tc.timeline = timeline.map((e) =>\n\t\t\t\t\t\te.releaseId === releaseId\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t...e,\n\t\t\t\t\t\t\t\t\treleaseId: plannedRelease.id,\n\t\t\t\t\t\t\t\t\tkind: \"date_only\",\n\t\t\t\t\t\t\t\t\tvalidityPeriod: { firstDay, lastDay },\n\t\t\t\t\t\t\t\t\tpublishTime: cs.closeTime ?? now(),\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: e,\n\t\t\t\t\t);\n\t\t\t\t\treturn { changeSet: copy(cs), publishTime: cs.closeTime, releases: cut };\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync updateFromMain({ id, chainId, idempotencyKey }) {\n\t\t\treturn once(idempotencyKey, [\"updateFromMain\", id, chainId], async () => {\n\t\t\t\tconst cs = open(id);\n\t\t\t\tif (!chainId) refuseWithheld(id);\n\t\t\t\tconst chains = chainId ? cs.chains.filter((ch) => ch.id === chainId) : cs.chains;\n\t\t\t\tif (chainId && chains.length === 0) throw notFound(\"Chain\", chainId);\n\t\t\t\tconst conflicted: PendingMergeRef[] = structuredClone(pendingMerges[id] ?? []);\n\t\t\t\tconst pending: PendingMergeRef[] = [];\n\t\t\t\tconst merged: string[] = [];\n\t\t\t\tfor (const chain of chains) {\n\t\t\t\t\tfor (const b of chain.branches) {\n\t\t\t\t\t\tconst ref = { branchId: b.id, contentId: chain.contentId };\n\t\t\t\t\t\tconst conflict = conflicts[b.id];\n\t\t\t\t\t\tif (stored.has(b.id)) pending.push(ref);\n\t\t\t\t\t\telse if (conflict) {\n\t\t\t\t\t\t\tstoreMerge(b.id, conflict);\n\t\t\t\t\t\t\tconflicted.push(ref);\n\t\t\t\t\t\t} else if (behind.has(b.id)) {\n\t\t\t\t\t\t\t// A clean merge: a merge Revision becomes the head.\n\t\t\t\t\t\t\tconst c = findContent(chain.contentId);\n\t\t\t\t\t\t\twriteHead({\n\t\t\t\t\t\t\t\tchangeSetId: id,\n\t\t\t\t\t\t\t\tchain,\n\t\t\t\t\t\t\t\tbranch: b,\n\t\t\t\t\t\t\t\tc,\n\t\t\t\t\t\t\t\tdata: structuredClone(dataOf(c, b.headRevisionId) ?? {}),\n\t\t\t\t\t\t\t\tcause: \"merge\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbehind.delete(b.id);\n\t\t\t\t\t\t\tmerged.push(b.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tchangeSet: copy(cs),\n\t\t\t\t\tmergedBranchIds: merged,\n\t\t\t\t\tconflicted,\n\t\t\t\t\tpending,\n\t\t\t\t\tendedBranchIds: [],\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\tasync discardChangeSet(id) {\n\t\t\tconst cs = open(id);\n\t\t\trefuseWithheld(id);\n\t\t\tcs.state = \"discarded\";\n\t\t\tcs.closeTime = now();\n\t\t\t// The Content born in it is gone, and its Chains with it.\n\t\t\tcs.chains = [];\n\t\t\treturn copy(cs);\n\t\t},\n\t\tasync listCheckResults(changeSetId) {\n\t\t\treturn standingsOf(find(changeSetId));\n\t\t},\n\t\tasync recordCheckResult({ changeSetId, requiredCheckId, heads, outcome, note }) {\n\t\t\tconst cs = open(changeSetId);\n\t\t\tif (outcome === \"waived\" && note.trim() === \"\") {\n\t\t\t\tthrow new InvalidInputError(\"a waived result needs a note saying why\");\n\t\t\t}\n\t\t\tif ([...note].length > CHECK_NOTE_MAX) {\n\t\t\t\tthrow new InvalidInputError(`a note is at most ${CHECK_NOTE_MAX} characters`);\n\t\t\t}\n\t\t\tconst check = requiredChecks.find((c) => c.id === requiredCheckId);\n\t\t\tif (!check) throw notFound(\"Required Check\", requiredCheckId);\n\t\t\tconst recording = recordersOf(requiredCheckId);\n\t\t\t// The caller is a member: the stub has no other kind of caller.\n\t\t\tif (\n\t\t\t\tauthzMode === \"guardian\" &&\n\t\t\t\t!recording.everyMember &&\n\t\t\t\t!recording.userIds.includes(userId)\n\t\t\t) {\n\t\t\t\tthrow new CheckResultDeniedError(\n\t\t\t\t\t`recording results of Required Check ${requiredCheckId} needs its recorder relation`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst subjects = subjectsOf(cs);\n\t\t\tconst named = Object.keys(heads);\n\t\t\tif (check.scope === \"branch\" && named.length !== 1) {\n\t\t\t\tthrow new InvalidInputError(\"a Branch-scope result names one head\");\n\t\t\t}\n\t\t\tif (check.scope === \"change_set\" && named.length !== subjects.length) {\n\t\t\t\tthrow new InvalidInputError(\"a Change Set-scope result names every head of the Change Set\");\n\t\t\t}\n\t\t\tfor (const key of named) {\n\t\t\t\tconst s = subjects.find((each) => each.key === key);\n\t\t\t\tif (!s)\n\t\t\t\t\tthrow new InvalidInputError(`heads name ${key}, which this Change Set doesn't hold`);\n\t\t\t\tif (s.revision !== heads[key]) {\n\t\t\t\t\tthrow new StaleHeadError({\n\t\t\t\t\t\tcontentId: s.contentId,\n\t\t\t\t\t\tbranchId: s.branchless ? \"\" : s.key,\n\t\t\t\t\t\texpectedHeadId: heads[key],\n\t\t\t\t\t\tcurrentHeadId: s.revision,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst result = {\n\t\t\t\tid: `cr_stub_${next++}`,\n\t\t\t\trequiredCheckId,\n\t\t\t\theads: { ...heads },\n\t\t\t\toutcome,\n\t\t\t\tnote,\n\t\t\t\trecordedBy: userId,\n\t\t\t\trecordTime: now(),\n\t\t\t};\n\t\t\tcheckResults.push({ ...result, changeSetId });\n\t\t\treturn structuredClone(result);\n\t\t},\n\n\t\tasync getEditingSettings() {\n\t\t\tconst byAccessor = [...editingOverrides].sort((a, b) =>\n\t\t\t\ta.blueprintAccessor < b.blueprintAccessor ? -1 : 1,\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tworkspace: structuredClone(workspaceEditing),\n\t\t\t\toverrides: byAccessor.map(overrideOut),\n\t\t\t};\n\t\t},\n\t\tasync getEffectiveEditingSettings(blueprintAccessor) {\n\t\t\tconst o = editingOverrides.find((x) => x.blueprintAccessor === blueprintAccessor.trim());\n\t\t\treturn {\n\t\t\t\teffective: effectiveOf(o),\n\t\t\t\teditingModeOverridden: (o?.editingMode ?? null) !== null,\n\t\t\t\teditingBlockOverridden: (o?.editingBlock ?? null) !== null,\n\t\t\t\tforceGroupOverridden: (o?.forceGroup ?? null) !== null,\n\t\t\t\tcallerInForceGroup: inForceGroup(effectiveOf(o).forceGroup),\n\t\t\t};\n\t\t},\n\t\tasync setEditingSettings(settings) {\n\t\t\tadminOnly();\n\t\t\tif (!editingModes.includes(settings.editingMode)) {\n\t\t\t\tthrow new InvalidInputError(\"the workspace's editing settings need an Editing Mode\");\n\t\t\t}\n\t\t\tworkspaceEditing = { ...settings, forceGroup: checkedGroup(settings.forceGroup) };\n\t\t\treturn structuredClone(workspaceEditing);\n\t\t},\n\t\tasync setBlueprintEditingOverride({\n\t\t\tblueprintAccessor,\n\t\t\teditingMode,\n\t\t\teditingBlock,\n\t\t\tforceGroup,\n\t\t}) {\n\t\t\tadminOnly();\n\t\t\tconst accessor = oneLine(blueprintAccessor, \"a Blueprint accessor\", BLUEPRINT_ACCESSOR_MAX);\n\t\t\tif (editingMode === null && editingBlock === null && forceGroup === null) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`an override of \"${accessor}\" sets the Editing Mode, the Editing Block, the Force Group or several`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst o: StubEditingOverride = {\n\t\t\t\tblueprintAccessor: accessor,\n\t\t\t\teditingMode,\n\t\t\t\teditingBlock,\n\t\t\t\tforceGroup: forceGroup === null ? null : checkedGroup(forceGroup),\n\t\t\t};\n\t\t\teditingOverrides = [...editingOverrides.filter((x) => x.blueprintAccessor !== accessor), o];\n\t\t\treturn overrideOut(o);\n\t\t},\n\t\tasync deleteBlueprintEditingOverride({ blueprintAccessor }) {\n\t\t\tadminOnly();\n\t\t\tconst accessor = blueprintAccessor.trim();\n\t\t\tif (!editingOverrides.some((x) => x.blueprintAccessor === accessor)) {\n\t\t\t\tthrow notFound(\"an editing override of\", accessor);\n\t\t\t}\n\t\t\teditingOverrides = editingOverrides.filter((x) => x.blueprintAccessor !== accessor);\n\t\t},\n\n\t\tasync listRequiredChecks() {\n\t\t\tconst byNameThenId = (a: RequiredCheck, b: RequiredCheck) =>\n\t\t\t\ta.name < b.name ? -1 : a.name > b.name ? 1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\t\t\treturn structuredClone([...requiredChecks].sort(byNameThenId));\n\t\t},\n\t\tasync createRequiredCheck(input) {\n\t\t\tconst checked = checkedRequiredCheck(input);\n\t\t\tif (requiredChecks.some((c) => c.name === checked.name)) {\n\t\t\t\tthrow new NameTakenError(checked.name);\n\t\t\t}\n\t\t\tconst check: RequiredCheck = { id: `rc_stub_${next++}`, ...checked };\n\t\t\trequiredChecks.push(check);\n\t\t\treturn structuredClone(check);\n\t\t},\n\t\tasync updateRequiredCheck({ id, ...input }) {\n\t\t\tconst checked = checkedRequiredCheck(input);\n\t\t\tconst check = requiredChecks.find((c) => c.id === id);\n\t\t\tif (!check) throw notFound(\"Required Check\", id);\n\t\t\tif (requiredChecks.some((c) => c.name === checked.name && c.id !== id)) {\n\t\t\t\tthrow new NameTakenError(checked.name);\n\t\t\t}\n\t\t\tObject.assign(check, checked);\n\t\t\treturn structuredClone(check);\n\t\t},\n\t\tasync deleteRequiredCheck({ id }) {\n\t\t\tif (!requiredChecks.some((c) => c.id === id)) throw notFound(\"Required Check\", id);\n\t\t\trequiredChecks = requiredChecks.filter((c) => c.id !== id);\n\t\t\trecorders.delete(id);\n\t\t},\n\t\tasync listRequiredCheckRecorders(requiredCheckId) {\n\t\t\treturn structuredClone(narrowable(requiredCheckId));\n\t\t},\n\t\tasync grantRequiredCheckRecorder({ requiredCheckId, recorder }) {\n\t\t\tconst held = narrowable(requiredCheckId);\n\t\t\tif (\"everyMember\" in recorder) {\n\t\t\t\trecorders.set(requiredCheckId, { ...held, everyMember: true });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!memberIds.includes(recorder.userId)) {\n\t\t\t\tthrow new InvalidInputError(`user ${recorder.userId} is not a member of the workspace`);\n\t\t\t}\n\t\t\trecorders.set(requiredCheckId, {\n\t\t\t\t...held,\n\t\t\t\tuserIds: [...new Set([...held.userIds, recorder.userId])].sort(),\n\t\t\t});\n\t\t},\n\t\tasync revokeRequiredCheckRecorder({ requiredCheckId, recorder }) {\n\t\t\tconst held = narrowable(requiredCheckId);\n\t\t\trecorders.set(\n\t\t\t\trequiredCheckId,\n\t\t\t\t\"everyMember\" in recorder\n\t\t\t\t\t? { ...held, everyMember: false }\n\t\t\t\t\t: { ...held, userIds: held.userIds.filter((u) => u !== recorder.userId) },\n\t\t\t);\n\t\t},\n\n\t\tasync searchBlueprints({ query }) {\n\t\t\tconst q = query.trim().toLocaleLowerCase();\n\t\t\treturn {\n\t\t\t\tblueprints: blueprints\n\t\t\t\t\t.filter((b) => !b.archived)\n\t\t\t\t\t.filter((b) => b.name.toLocaleLowerCase().includes(q))\n\t\t\t\t\t.filter((b) => releases.some((r) => r.blueprintId === b.id))\n\t\t\t\t\t.map((b) => ({ id: b.id, name: b.name })),\n\t\t\t\tnextPageToken: \"\",\n\t\t\t};\n\t\t},\n\t\tasync getBlueprints(ids) {\n\t\t\tif (ids.length > MAX_BLUEPRINT_IDS) {\n\t\t\t\tthrow new InvalidInputError(`at most ${MAX_BLUEPRINT_IDS} Blueprint ids`);\n\t\t\t}\n\t\t\treturn blueprints.filter((b) => ids.includes(b.id)).map((b) => ({ id: b.id, name: b.name }));\n\t\t},\n\t\tasync listBlueprintReleases(blueprintId) {\n\t\t\treturn releases\n\t\t\t\t.filter((r) => r.blueprintId === blueprintId)\n\t\t\t\t.map((r) => ({\n\t\t\t\t\tid: r.id,\n\t\t\t\t\tblueprintId: r.blueprintId,\n\t\t\t\t\tname: r.name ?? r.id,\n\t\t\t\t\treleaseTime: r.releaseTime ?? STUB_NOW,\n\t\t\t\t\trefusals: (r.refusals ?? []).map((v) => ({ ...v })),\n\t\t\t\t}));\n\t\t},\n\n\t\tasync listCollections() {\n\t\t\treturn [...collections].sort(collectionOrder).map((c) => ({ ...c }));\n\t\t},\n\t\tasync createCollection({ name: raw, parentId = \"\", restricted = false }) {\n\t\t\tconst name = oneLine(raw, \"a Collection's name\", COLLECTION_NAME_MAX);\n\t\t\tif (parentId !== \"\") findCollection(parentId);\n\t\t\tif (restricted && authzMode === \"workspace\") {\n\t\t\t\tthrow new RestrictionUnavailableError(WORKSPACE_MODE_REFUSAL);\n\t\t\t}\n\t\t\tif (siblingNamed(parentId, name)) throw new NameTakenError(name);\n\t\t\tconst collection: Collection = { id: `col_stub_${next++}`, name, parentId, restricted };\n\t\t\tcollections.push(collection);\n\t\t\tif (restricted) grants.set(collection.id, [{ userId, level: \"owner\" }]);\n\t\t\treturn { ...collection };\n\t\t},\n\t\tasync renameCollection({ id, name: raw }) {\n\t\t\tconst name = oneLine(raw, \"a Collection's name\", COLLECTION_NAME_MAX);\n\t\t\tconst collection = findCollection(id);\n\t\t\tif (siblingNamed(collection.parentId, name, id)) throw new NameTakenError(name);\n\t\t\tcollection.name = name;\n\t\t\treturn { ...collection };\n\t\t},\n\t\tasync moveCollection({ id, parentId }) {\n\t\t\tconst collection = findCollection(id);\n\t\t\tfor (let at = parentId; at !== \"\"; at = findCollection(at).parentId) {\n\t\t\t\tif (at === id) {\n\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t`Collection ${id} can't move under itself or a Collection under it`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// As over the wire: a move sends no name, so the refusal names none.\n\t\t\tif (siblingNamed(parentId, collection.name, id)) throw new NameTakenError(\"\");\n\t\t\tcollection.parentId = parentId;\n\t\t\treturn { ...collection };\n\t\t},\n\t\tasync removeCollection({ id }) {\n\t\t\tfindCollection(id);\n\t\t\tif (collections.some((c) => c.parentId === id)) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`Collection ${id} has Collections under it: remove or move those first`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcollections.splice(\n\t\t\t\tcollections.findIndex((c) => c.id === id),\n\t\t\t\t1,\n\t\t\t);\n\t\t\tgrants.delete(id);\n\t\t\tconst unfiled: string[] = [];\n\t\t\tfor (const c of contents) {\n\t\t\t\tif (c.collectionIds.includes(id)) {\n\t\t\t\t\tc.collectionIds = c.collectionIds.filter((each) => each !== id);\n\t\t\t\t\tunfiled.push(c.id);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn unfiled;\n\t\t},\n\t\tasync setCollectionRestricted({ id, restricted, acknowledgeDisclosure = false }) {\n\t\t\tif (restricted && authzMode === \"workspace\") {\n\t\t\t\tthrow new RestrictionUnavailableError(WORKSPACE_MODE_REFUSAL);\n\t\t\t}\n\t\t\tconst collection = findCollection(id);\n\t\t\tif (collection.restricted === restricted) return { ...collection };\n\t\t\tif (!restricted && !acknowledgeDisclosure) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`unrestricting Collection ${id} discloses its Content to every viewer: ` +\n\t\t\t\t\t\t\"confirm it with acknowledge_disclosure\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tcollection.restricted = restricted;\n\t\t\t// The one who restricts it owns it; opening it clears every grant.\n\t\t\tif (restricted) grants.set(id, [{ userId, level: \"owner\" }]);\n\t\t\telse grants.delete(id);\n\t\t\treturn { ...collection };\n\t\t},\n\t\tasync listCollectionGrants(collectionId) {\n\t\t\tmanageable(collectionId);\n\t\t\treturn structuredClone(grants.get(collectionId) ?? []).sort((a, b) =>\n\t\t\t\ta.userId < b.userId ? -1 : a.userId > b.userId ? 1 : 0,\n\t\t\t);\n\t\t},\n\t\tasync grantCollectionAccess({ collectionId, userId: grantee, level }) {\n\t\t\tmanageable(collectionId);\n\t\t\tif (level !== \"viewer\" && level !== \"editor\") {\n\t\t\t\tthrow new InvalidInputError(\"a grant is viewer or editor\");\n\t\t\t}\n\t\t\tif (!memberIds.includes(grantee)) {\n\t\t\t\tthrow new InvalidInputError(`${grantee} is not a member of the workspace`);\n\t\t\t}\n\t\t\tconst held = grants.get(collectionId) ?? [];\n\t\t\t// The owner stays owner: a grant never lowers what restricting gave.\n\t\t\tif (held.some((g) => g.level === \"owner\" && g.userId === grantee)) return;\n\t\t\tgrants.set(collectionId, [\n\t\t\t\t...held.filter((g) => g.userId !== grantee),\n\t\t\t\t{ userId: grantee, level },\n\t\t\t]);\n\t\t},\n\t\tasync revokeCollectionAccess({ collectionId, userId: grantee }) {\n\t\t\tmanageable(collectionId);\n\t\t\tgrants.set(\n\t\t\t\tcollectionId,\n\t\t\t\t(grants.get(collectionId) ?? []).filter((g) => g.userId !== grantee || g.level === \"owner\"),\n\t\t\t);\n\t\t},\n\t\tasync listContents(input = {}) {\n\t\t\tconst view: ContentView = input.view ?? { kind: \"main\" };\n\t\t\tconst search = (input.search ?? \"\").trim();\n\t\t\tif (search !== \"\" && view.kind === \"in_force\") {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\"filter.search: Editor Search covers Main and open Branch heads, never Releases\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif ([...search].length > CONTENT_SEARCH_MAX) {\n\t\t\t\tthrow new InvalidInputError(`filter.search is at most ${CONTENT_SEARCH_MAX} characters`);\n\t\t\t}\n\t\t\tif (input.collectionId && !collections.some((c) => c.id === input.collectionId)) {\n\t\t\t\tthrow notFound(\"Collection\", input.collectionId);\n\t\t\t}\n\t\t\tif (view.kind === \"change_set\") find(view.changeSetId);\n\n\t\t\tconst rows = contents\n\t\t\t\t// Archived Content is put aside: every view leaves it out (ADR 0015).\n\t\t\t\t.filter((c) => !c.archiveTime)\n\t\t\t\t.filter((c) => !input.collectionId || c.collectionIds.includes(input.collectionId))\n\t\t\t\t.filter((c) => !input.blueprintIds?.length || input.blueprintIds.includes(c.blueprintId))\n\t\t\t\t.filter((c) => !input.assigneeId || (c.assigneeIds ?? []).includes(input.assigneeId))\n\t\t\t\t.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n\t\t\t\t.flatMap((c) => readsOf(c, view, search));\n\t\t\tconst size = Math.min(input.pageSize || 50, 200);\n\t\t\tconst start = input.pageToken ? Number(input.pageToken) : 0;\n\t\t\treturn {\n\t\t\t\tcontents: rows.slice(start, start + size),\n\t\t\t\tnextPageToken: start + size < rows.length ? String(start + size) : \"\",\n\t\t\t};\n\t\t},\n\t\tasync createContent({ changeSetId, blueprintReleaseId: asked, copyFrom }) {\n\t\t\tconst cs = open(changeSetId);\n\t\t\tlet data: Record<string, unknown> = {};\n\t\t\tlet blueprintReleaseId = asked;\n\t\t\tif (copyFrom) {\n\t\t\t\tconst sourceRevision =\n\t\t\t\t\t\"revisionId\" in copyFrom\n\t\t\t\t\t\t? copyFrom.revisionId\n\t\t\t\t\t\t: contents.find((c) => c.inForce?.releaseId === copyFrom.releaseId)?.inForce\n\t\t\t\t\t\t\t\t?.revisionId;\n\t\t\t\tconst source = contents.find((c) => sourceRevision && dataOf(c, sourceRevision));\n\t\t\t\tif (!source || !sourceRevision) {\n\t\t\t\t\tthrow notFound(\"copy source\", JSON.stringify(copyFrom));\n\t\t\t\t}\n\t\t\t\tdata = structuredClone(dataOf(source, sourceRevision) ?? {});\n\t\t\t\tblueprintReleaseId = asked || source.blueprintReleaseId;\n\t\t\t}\n\t\t\tconst release = releases.find((r) => r.id === blueprintReleaseId);\n\t\t\tif (!release) {\n\t\t\t\tthrow new ContentRefusedError(`Blueprint Release ${blueprintReleaseId} can't be loaded`, [\n\t\t\t\t\t{ source: \"contenthub\", code: \"release_not_found\", path: \"\" },\n\t\t\t\t]);\n\t\t\t}\n\t\t\tif (release.refusals?.length) {\n\t\t\t\tthrow new ContentRefusedError(\n\t\t\t\t\t`Blueprint Release ${blueprintReleaseId} can't be loaded`,\n\t\t\t\t\trelease.refusals.map((r) => ({ ...r })),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst n = next++;\n\t\t\tconst id = `content_stub_${n}`;\n\t\t\tconst branchId = `br_stub_${n}`;\n\t\t\tconst revisionId = `rev_stub_${n}`;\n\t\t\tcontents.push({\n\t\t\t\tid,\n\t\t\t\tblueprintId: release.blueprintId,\n\t\t\t\tblueprintReleaseId,\n\t\t\t\tcollectionIds: [],\n\t\t\t\tbranches: {\n\t\t\t\t\t[changeSetId]: { branchId, revisionId, data, revisionCreateTime: now() },\n\t\t\t\t},\n\t\t\t});\n\t\t\tcs.chains.push({\n\t\t\t\tid: `chain_stub_${n}`,\n\t\t\t\tcontentId: id,\n\t\t\t\tborn: true,\n\t\t\t\tbranches: [{ id: branchId, position: 0, kind: \"editorial\", headRevisionId: revisionId }],\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tblueprintId: release.blueprintId,\n\t\t\t\tblueprintReleaseId,\n\t\t\t\trevisionId,\n\t\t\t\tdata: structuredClone(data),\n\t\t\t\tchangeSetId,\n\t\t\t\tbranchId,\n\t\t\t\trevisionCreateTime: now(),\n\t\t\t\treleaseId: \"\",\n\t\t\t};\n\t\t},\n\n\t\tasync saveRevision({ idempotencyKey, ...request }) {\n\t\t\tif (!idempotencyKey) return saveOnce(request);\n\t\t\t// A repeat answers the first save and writes nothing; another\n\t\t\t// request under the same key is refused (CONTEXT.md, Idempotency Key).\n\t\t\tconst asked = JSON.stringify(request);\n\t\t\tconst kept = savedUnder.get(idempotencyKey);\n\t\t\tif (kept) {\n\t\t\t\tif (kept.asked !== asked) {\n\t\t\t\t\tthrow new InvalidInputError(`idempotency key ${idempotencyKey} names another save`);\n\t\t\t\t}\n\t\t\t\treturn structuredClone(kept.content);\n\t\t\t}\n\t\t\tconst content = await saveOnce(request);\n\t\t\tsavedUnder.set(idempotencyKey, { asked, content: structuredClone(content) });\n\t\t\treturn content;\n\t\t},\n\n\t\tasync getContent({ id, changeSetId, branchId }) {\n\t\t\tconst c = findContent(id);\n\t\t\tconst view: ContentView = changeSetId\n\t\t\t\t? { kind: \"change_set\", changeSetId }\n\t\t\t\t: { kind: \"main\" };\n\t\t\tif (branchId && !changeSetId) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\"branch_id names a Branch of a Change Set: give its change_set_id too\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Born in an open Change Set, it exists only there, as the service says.\n\t\t\tlet [content] = readsOf(c, view, \"\");\n\t\t\tif (!content) throw notFound(\"Content\", id);\n\t\t\tif (branchId && branchId !== content.branchId) {\n\t\t\t\t// An earlier Branch of the Chain, at its own head.\n\t\t\t\tconst branch = changeSets\n\t\t\t\t\t.find((cs) => cs.id === changeSetId)\n\t\t\t\t\t?.chains.find((ch) => ch.contentId === id)\n\t\t\t\t\t?.branches.find((b) => b.id === branchId);\n\t\t\t\tif (!branch) throw notFound(\"Branch\", branchId);\n\t\t\t\tconst rev = revisionsOf(c).find((r) => r.id === branch.headRevisionId);\n\t\t\t\tconst data = rev?.data ?? (c.main?.revisionId === branch.headRevisionId ? c.main.data : {});\n\t\t\t\tcontent = {\n\t\t\t\t\t...content,\n\t\t\t\t\trevisionId: branch.headRevisionId,\n\t\t\t\t\tdata: structuredClone(data),\n\t\t\t\t\tbranchId,\n\t\t\t\t\trevisionCreateTime: rev?.createTime ?? content.revisionCreateTime,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst release = resolved[c.blueprintReleaseId];\n\t\t\treturn {\n\t\t\t\tcontent,\n\t\t\t\tblueprintRelease: release ? structuredClone(release) : undefined,\n\t\t\t\tattributes: attributesOf(c),\n\t\t\t};\n\t\t},\n\t\tasync getTimeline(contentId) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tconst isOpen = (csId: string) => changeSets.find((cs) => cs.id === csId)?.state === \"open\";\n\t\t\treturn structuredClone({\n\t\t\t\tentries: c.timeline ?? [],\n\t\t\t\tplannedReleases: (c.plannedReleases ?? []).filter((p) => isOpen(p.changeSetId)),\n\t\t\t});\n\t\t},\n\t\tasync listRevisions({ target, pageSize, pageToken }) {\n\t\t\tlet found: (Revision & { data?: unknown })[];\n\t\t\tif (\"contentId\" in target) {\n\t\t\t\tconst c = findContent(target.contentId);\n\t\t\t\t// versionkit lists by Item only once it is published (#65).\n\t\t\t\tif (!c.main) throw notFound(\"Content\", target.contentId);\n\t\t\t\tfound = revisionsOf(c);\n\t\t\t} else {\n\t\t\t\tconst owner = contents.find((c) =>\n\t\t\t\t\trevisionsOf(c).some((r) => r.branchId === target.branchId),\n\t\t\t\t);\n\t\t\t\tif (!owner) throw notFound(\"Branch\", target.branchId);\n\t\t\t\tfound = revisionsOf(owner).filter((r) => r.branchId === target.branchId);\n\t\t\t}\n\t\t\tconst size = Math.min(pageSize || 50, 200);\n\t\t\tconst start = pageToken ? Number(pageToken) : 0;\n\t\t\treturn {\n\t\t\t\trevisions: found.slice(start, start + size).map(({ data: _data, ...r }) => r),\n\t\t\t\tnextPageToken: start + size < found.length ? String(start + size) : \"\",\n\t\t\t};\n\t\t},\n\t\tasync compare({ revisionId, base }) {\n\t\t\tconst c = contents.find((each) => revisionsOf(each).some((r) => r.id === revisionId));\n\t\t\tif (!c) throw notFound(\"Revision\", revisionId);\n\t\t\tconst all = revisionsOf(c);\n\t\t\tconst after = all.find((r) => r.id === revisionId) as Revision;\n\t\t\tlet baseId: string;\n\t\t\tif (base.kind === \"revision\") baseId = base.revisionId;\n\t\t\telse if (base.kind === \"main_head\") {\n\t\t\t\tif (!c.main) {\n\t\t\t\t\tthrow new InvalidInputError(\"the Content is not published: it has no Main Branch\");\n\t\t\t\t}\n\t\t\t\tbaseId = c.main.revisionId;\n\t\t\t} else baseId = all.find((r) => r.branchId === base.branchId)?.parentId ?? \"\";\n\t\t\tconst before = all.find((r) => r.id === baseId);\n\t\t\tif (!before) throw notFound(\"Revision\", baseId);\n\t\t\tconst a = dataOf(c, after.id) ?? {};\n\t\t\tconst b = dataOf(c, before.id) ?? {};\n\t\t\tconst changes: FieldChange[] = [];\n\t\t\tfor (const key of [...new Set([...Object.keys(a), ...Object.keys(b)])]) {\n\t\t\t\tif (!(key in b)) changes.push({ path: `/${key}`, kind: \"added\", after: a[key] });\n\t\t\t\telse if (!(key in a)) changes.push({ path: `/${key}`, kind: \"removed\", before: b[key] });\n\t\t\t\telse if (JSON.stringify(a[key]) !== JSON.stringify(b[key])) {\n\t\t\t\t\tchanges.push({ path: `/${key}`, kind: \"changed\", before: b[key], after: a[key] });\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst strip = ({ data: _data, ...r }: Revision & { data?: unknown }) => r;\n\t\t\treturn { base: strip(before), revision: strip(after), changes };\n\t\t},\n\t\tasync listReferences({ contentId, revisionId }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\treturn (c.edges ?? [])\n\t\t\t\t.filter((e) => e.sourceRevisionId === revisionId)\n\t\t\t\t.map((e) => ({ ...e }));\n\t\t},\n\t\tasync listReferrers({ contentId, includeOpenChangeSets, pageSize, pageToken }) {\n\t\t\tfindContent(contentId);\n\t\t\t// Paged as the service pages, by position in its order.\n\t\t\tconst page = (rows: Referrer[]): ReferrerList => {\n\t\t\t\tconst size = Math.min(pageSize || 100, 1000);\n\t\t\t\tconst start = pageToken ? Number(pageToken) : 0;\n\t\t\t\treturn {\n\t\t\t\t\treferrers: rows.slice(start, start + size),\n\t\t\t\t\tnextPageToken: start + size < rows.length ? String(start + size) : \"\",\n\t\t\t\t};\n\t\t\t};\n\t\t\tconst fromReleases = contents.flatMap((other) =>\n\t\t\t\t(other.edges ?? [])\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(e) =>\n\t\t\t\t\t\t\te.targetContentId === contentId && other.inForce?.revisionId === e.sourceRevisionId,\n\t\t\t\t\t)\n\t\t\t\t\t.map((e) => ({\n\t\t\t\t\t\tedge: { ...e },\n\t\t\t\t\t\treleaseId: other.inForce?.releaseId ?? \"\",\n\t\t\t\t\t\tchangeSetId: \"\",\n\t\t\t\t\t\tbranchId: \"\",\n\t\t\t\t\t})),\n\t\t\t);\n\t\t\tif (!includeOpenChangeSets) return page(fromReleases);\n\t\t\tconst fromBranches = contents.flatMap((other) =>\n\t\t\t\tObject.entries(other.branches).flatMap(([csId, head]) =>\n\t\t\t\t\tchangeSets.find((cs) => cs.id === csId)?.state !== \"open\"\n\t\t\t\t\t\t? []\n\t\t\t\t\t\t: (other.edges ?? [])\n\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t(e) => e.targetContentId === contentId && e.sourceRevisionId === head.revisionId,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.map((e) => ({\n\t\t\t\t\t\t\t\t\tedge: { ...e },\n\t\t\t\t\t\t\t\t\treleaseId: \"\",\n\t\t\t\t\t\t\t\t\tchangeSetId: csId,\n\t\t\t\t\t\t\t\t\tbranchId: head.branchId,\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn page([...fromReleases, ...fromBranches]);\n\t\t},\n\t\tasync listOutdatedPins(input) {\n\t\t\tlet revisionId: string | undefined;\n\t\t\tif (\"revisionId\" in input) revisionId = input.revisionId;\n\t\t\telse {\n\t\t\t\tfor (const c of contents) {\n\t\t\t\t\tconst head = Object.values(c.branches).find((h) => h.branchId === input.branchId);\n\t\t\t\t\tif (head) revisionId = head.revisionId;\n\t\t\t\t}\n\t\t\t\tif (!revisionId) throw notFound(\"Branch\", input.branchId);\n\t\t\t}\n\t\t\tconst edges: Edge[] = contents.flatMap((c) =>\n\t\t\t\t(c.edges ?? []).filter((e) => e.sourceRevisionId === revisionId),\n\t\t\t);\n\t\t\treturn edges\n\t\t\t\t.filter((e) => e.pinReleaseId !== \"\")\n\t\t\t\t.flatMap((e) => {\n\t\t\t\t\tconst target = contents.find((c) => c.id === e.targetContentId);\n\t\t\t\t\tconst inForce = target?.inForce?.releaseId ?? \"\";\n\t\t\t\t\tif (inForce === e.pinReleaseId) return [];\n\t\t\t\t\treturn [{ edge: { ...e }, supersededByReleaseId: inForce, inForceReleaseId: inForce }];\n\t\t\t\t});\n\t\t},\n\n\t\tasync setContentCollections({ contentId, collectionIds }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tconst unique = [...new Set(collectionIds)];\n\t\t\tif (unique.length > 100) throw new InvalidInputError(\"at most 100 Collections\");\n\t\t\tfor (const id of unique) {\n\t\t\t\tif (!collections.some((col) => col.id === id)) throw notFound(\"Collection\", id);\n\t\t\t}\n\t\t\tc.collectionIds = unique.sort();\n\t\t\treturn [...c.collectionIds];\n\t\t},\n\t\tasync setContentAssignees({ contentId, assigneeIds }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (new Set(assigneeIds).size !== assigneeIds.length) {\n\t\t\t\tthrow new InvalidInputError(\"each assignee is given once\");\n\t\t\t}\n\t\t\tif (assigneeIds.length > 50) throw new InvalidInputError(\"at most 50 assignees\");\n\t\t\tc.assigneeIds = [...assigneeIds];\n\t\t\treturn attributesOf(c);\n\t\t},\n\t\tasync blockContent({ contentId, blockReasonId, allowedUserIds }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (!reasons.some((r) => r.id === blockReasonId)) {\n\t\t\t\tthrow notFound(\"Block Reason\", blockReasonId);\n\t\t\t}\n\t\t\tif (new Set(allowedUserIds).size !== allowedUserIds.length) {\n\t\t\t\tthrow new InvalidInputError(\"each allowed user is given once\");\n\t\t\t}\n\t\t\tc.block = {\n\t\t\t\tblockReasonId,\n\t\t\t\tallowedUserIds: [...allowedUserIds],\n\t\t\t\tblockedBy: userId,\n\t\t\t\tblockTime: now(),\n\t\t\t};\n\t\t\treturn attributesOf(c);\n\t\t},\n\t\tasync unblockContent(contentId) {\n\t\t\tconst c = findContent(contentId);\n\t\t\t// An Editing Block ends only with its Direct Edit (ADR 0022).\n\t\t\tif (!c.block && c.editingBlock) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`Content ${contentId} is being edited by ${c.editingBlock.editorId} in a Direct Edit: its Editing Block can't be lifted`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tc.block = undefined;\n\t\t\treturn attributesOf(c);\n\t\t},\n\t\tasync archiveContent(contentId) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (c.archiveTime) return attributesOf(c);\n\t\t\tif (!c.main) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`Content ${contentId} is not published: discard its Change Set instead of archiving it`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (inForceOnOrAfter(c.timeline ?? [], today())) {\n\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t`Content ${contentId} has a Release In Force today or later: end its force first`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tc.archiveTime = now();\n\t\t\treturn attributesOf(c);\n\t\t},\n\t\tasync unarchiveContent(contentId) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tc.archiveTime = undefined;\n\t\t\treturn attributesOf(c);\n\t\t},\n\n\t\tasync openDirectEdit({ contentId, effectiveOn, idempotencyKey }) {\n\t\t\treturn once(idempotencyKey, [\"openDirectEdit\", contentId, effectiveOn], async () => {\n\t\t\t\tconst c = findContent(contentId);\n\t\t\t\tconst mine = changeSets.find(\n\t\t\t\t\t(cs) =>\n\t\t\t\t\t\tcs.kind === \"direct_edit\" &&\n\t\t\t\t\t\tcs.state === \"open\" &&\n\t\t\t\t\t\tcs.editorId === userId &&\n\t\t\t\t\t\tcs.chains[0]?.contentId === contentId,\n\t\t\t\t);\n\t\t\t\tif (mine) {\n\t\t\t\t\tconst [content] = readsOf(c, { kind: \"change_set\", changeSetId: mine.id }, \"\");\n\t\t\t\t\treturn { changeSet: copy(mine), content, reopened: true };\n\t\t\t\t}\n\t\t\t\tconst dated = datedContent(c);\n\t\t\t\tif (!dated && effectiveOn) {\n\t\t\t\t\tthrow new InvalidInputError(\"effective_on is refused for undated Content\");\n\t\t\t\t}\n\t\t\t\t// The stub's Content names its Blueprint by id where a Release\n\t\t\t\t// names no accessor, as its Required Checks do.\n\t\t\t\tconst accessor = accessorOf(c);\n\t\t\t\tconst effective = effectiveOf(\n\t\t\t\t\teditingOverrides.find((o) => o.blueprintAccessor === accessor),\n\t\t\t\t);\n\t\t\t\tconst mode = effective.editingMode;\n\t\t\t\tif (c.main && mode === \"change_sets\") {\n\t\t\t\t\tthrow new EditingModeRefusedError(contentId, accessor, mode);\n\t\t\t\t}\n\t\t\t\tif (c.editingBlock && c.editingBlock.editorId !== userId) {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"editing_blocked\",\n\t\t\t\t\t\t`Content ${contentId} is being edited by ${c.editingBlock.editorId} in a Direct Edit`,\n\t\t\t\t\t\tcontentId,\n\t\t\t\t\t\tc.editingBlock.editorId,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// Dated Content forks from the Release In Force on its day, today\n\t\t\t\t// by default, and carries every later wording forward (#270).\n\t\t\t\tconst day = dated ? effectiveOn || today() : undefined;\n\t\t\t\tconst started = await client.startEditing({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tchangeSetName: `Direct Edit of ${contentId}`,\n\t\t\t\t\teffectiveOn: day,\n\t\t\t\t});\n\t\t\t\tconst cs = find(started.changeSet.id);\n\t\t\t\tcs.kind = \"direct_edit\";\n\t\t\t\tcs.editorId = userId;\n\t\t\t\tconst chain = cs.chains[0];\n\t\t\t\tif (day && chain?.branches[0]) {\n\t\t\t\t\tconst timeline = c.timeline ?? [];\n\t\t\t\t\tconst inForce = (e: TimelineEntry) =>\n\t\t\t\t\t\t!!e.validityPeriod &&\n\t\t\t\t\t\te.validityPeriod.firstDay <= day &&\n\t\t\t\t\t\t(e.validityPeriod.lastDay === \"\" || day <= e.validityPeriod.lastDay);\n\t\t\t\t\tconst fork = [...timeline].reverse().find(inForce);\n\t\t\t\t\tchain.branches[0].effectiveOn = day;\n\t\t\t\t\tchain.branches[0].carriedReleaseId = fork?.releaseId ?? \"\";\n\t\t\t\t\tfor (const e of timeline) {\n\t\t\t\t\t\tif (!e.validityPeriod || e.validityPeriod.firstDay <= day) continue;\n\t\t\t\t\t\tchain.branches.push({\n\t\t\t\t\t\t\tid: `br_stub_${next++}`,\n\t\t\t\t\t\t\tposition: chain.branches.length,\n\t\t\t\t\t\t\tkind: \"carry_forward\",\n\t\t\t\t\t\t\theadRevisionId: e.revisionId,\n\t\t\t\t\t\t\teffectiveOn: e.validityPeriod.firstDay,\n\t\t\t\t\t\t\tcarriedReleaseId: e.releaseId,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (effective.editingBlock) {\n\t\t\t\t\tc.editingBlock = { editorId: userId, changeSetId: cs.id, blockTime: now() };\n\t\t\t\t}\n\t\t\t\treturn { changeSet: copy(cs), content: started.content, reopened: false };\n\t\t\t});\n\t\t},\n\t\tasync previewDirectEditPublish({ id, validityLastDay }) {\n\t\t\tconst cs = find(id);\n\t\t\tif (cs.kind !== \"direct_edit\") {\n\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\"not_a_direct_edit\",\n\t\t\t\t\t`Change Set ${id} is not a Direct Edit`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn structuredClone(directEditPlanOf(cs, validityLastDay));\n\t\t},\n\t\tasync publishDirectEdit({\n\t\t\tid,\n\t\t\texpectedHeadId,\n\t\t\treleaseSpec,\n\t\t\tvalidityLastDay,\n\t\t\tcarryForward,\n\t\t\tidempotencyKey,\n\t\t}) {\n\t\t\treturn once(\n\t\t\t\tidempotencyKey,\n\t\t\t\t[\"publishDirectEdit\", id, expectedHeadId, releaseSpec, validityLastDay, carryForward],\n\t\t\t\tasync () => {\n\t\t\t\t\tconst cs = find(id);\n\t\t\t\t\tif (cs.kind !== \"direct_edit\") {\n\t\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\t\"not_a_direct_edit\",\n\t\t\t\t\t\t\t`Change Set ${id} is not a Direct Edit`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// One transaction, as the service's: a refusal leaves nothing planned.\n\t\t\t\t\tconst c = findContent(cs.chains[0]?.contentId ?? \"\");\n\t\t\t\t\tconst before = { cs: structuredClone(cs), c: structuredClone(c) };\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await publishDirectEditOnce(cs, expectedHeadId, releaseSpec, {\n\t\t\t\t\t\t\tvalidityLastDay,\n\t\t\t\t\t\t\tcarryForward,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\trestore(cs, before.cs);\n\t\t\t\t\t\trestore(c, before.c);\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync saveAndPublishDirectEdit({\n\t\t\tid,\n\t\t\texpectedHeadId,\n\t\t\tdata,\n\t\t\tfieldMask,\n\t\t\treleaseSpec,\n\t\t\tvalidityLastDay,\n\t\t\tcarryForward,\n\t\t\tidempotencyKey,\n\t\t}) {\n\t\t\treturn once(\n\t\t\t\tidempotencyKey,\n\t\t\t\t[\n\t\t\t\t\t\"saveAndPublishDirectEdit\",\n\t\t\t\t\tid,\n\t\t\t\t\texpectedHeadId,\n\t\t\t\t\tdata,\n\t\t\t\t\tfieldMask,\n\t\t\t\t\treleaseSpec,\n\t\t\t\t\tvalidityLastDay,\n\t\t\t\t\tcarryForward,\n\t\t\t\t],\n\t\t\t\tasync () => {\n\t\t\t\t\tconst cs = find(id);\n\t\t\t\t\tif (cs.kind !== \"direct_edit\") {\n\t\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\t\"not_a_direct_edit\",\n\t\t\t\t\t\t\t`Change Set ${id} is not a Direct Edit`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst branch = cs.chains[0]?.branches[0];\n\t\t\t\t\tif (!branch) throw new Error(`Direct Edit ${id} has no Branch`);\n\t\t\t\t\t// One transaction, as the service's: refused as a whole.\n\t\t\t\t\tconst c = findContent(cs.chains[0]?.contentId ?? \"\");\n\t\t\t\t\tconst before = { cs: structuredClone(cs), c: structuredClone(c) };\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Not through client.saveRevision: one request, as the service's.\n\t\t\t\t\t\tconst content = await saveOnce({\n\t\t\t\t\t\t\tchangeSetId: id,\n\t\t\t\t\t\t\tbranchId: branch.id,\n\t\t\t\t\t\t\texpectedHeadId,\n\t\t\t\t\t\t\tdata,\n\t\t\t\t\t\t\tfieldMask,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst outcome = await publishDirectEditOnce(cs, content.revisionId, releaseSpec, {\n\t\t\t\t\t\t\tvalidityLastDay,\n\t\t\t\t\t\t\tcarryForward,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn { content, outcome };\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\trestore(cs, before.cs);\n\t\t\t\t\t\trestore(c, before.c);\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync discardDirectEdit({ id, idempotencyKey }) {\n\t\t\treturn once(idempotencyKey, [\"discardDirectEdit\", id], async () => {\n\t\t\t\tconst cs = find(id);\n\t\t\t\tif (cs.kind !== \"direct_edit\") {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"not_a_direct_edit\",\n\t\t\t\t\t\t`Change Set ${id} is not a Direct Edit`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst discarded = await client.discardChangeSet(id);\n\t\t\t\tfor (const c of contents) {\n\t\t\t\t\tif (c.editingBlock?.changeSetId === id) c.editingBlock = undefined;\n\t\t\t\t}\n\t\t\t\treturn discarded;\n\t\t\t});\n\t\t},\n\t\tasync forceDirectEdit({ id, idempotencyKey }) {\n\t\t\treturn once(idempotencyKey, [\"forceDirectEdit\", id], async () => {\n\t\t\t\tconst cs = find(id);\n\t\t\t\tif (cs.kind !== \"direct_edit\") {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"not_a_direct_edit\",\n\t\t\t\t\t\t`Change Set ${id} is not a Direct Edit`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst contentId = cs.chains[0]?.contentId ?? \"\";\n\t\t\t\tconst c = findContent(contentId);\n\t\t\t\tif (cs.state !== \"open\" || c.editingBlock?.changeSetId !== id) {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"no_editing_block\",\n\t\t\t\t\t\t`Change Set ${id} holds no Editing Block`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst group = effectiveOf(\n\t\t\t\t\teditingOverrides.find((o) => o.blueprintAccessor === accessorOf(c)),\n\t\t\t\t).forceGroup;\n\t\t\t\tif (!inForceGroup(group)) {\n\t\t\t\t\tthrow new AccessDeniedError(\n\t\t\t\t\t\t`forcing the Editing Block of Content ${contentId} needs the Force Group`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst own = changeSets.find(\n\t\t\t\t\t(each) =>\n\t\t\t\t\t\teach.kind === \"direct_edit\" &&\n\t\t\t\t\t\teach.state === \"open\" &&\n\t\t\t\t\t\teach.editorId === userId &&\n\t\t\t\t\t\teach.chains[0]?.contentId === contentId,\n\t\t\t\t);\n\t\t\t\tif (own) {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"own_direct_edit\",\n\t\t\t\t\t\t`you have a Direct Edit of Content ${contentId}, ${own.id}`,\n\t\t\t\t\t\tcontentId,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst previousEditorId = cs.editorId ?? \"\";\n\t\t\t\tcs.editorId = userId;\n\t\t\t\tc.editingBlock = { editorId: userId, changeSetId: id, blockTime: now() };\n\t\t\t\tconst [content] = readsOf(c, { kind: \"change_set\", changeSetId: id }, \"\");\n\t\t\t\treturn { changeSet: copy(cs), content, previousEditorId };\n\t\t\t});\n\t\t},\n\t\tasync startEditing({ contentId, changeSetId, effectiveOn = \"\", changeSetName = \"\" }) {\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (!c.main) {\n\t\t\t\tthrow new InvalidInputError(`Content ${contentId} is not published`);\n\t\t\t}\n\t\t\tcheckEditable(c);\n\t\t\tif (datedContent(c) && !DAY.test(effectiveOn)) {\n\t\t\t\tthrow new InvalidInputError(\"effective_on is required for Dated Content, as YYYY-MM-DD\");\n\t\t\t}\n\t\t\tif (!datedContent(c) && effectiveOn !== \"\") {\n\t\t\t\tthrow new InvalidInputError(\"effective_on is refused for undated Content\");\n\t\t\t}\n\t\t\tlet cs: ChangeSet;\n\t\t\tif (changeSetId) {\n\t\t\t\tcs = open(changeSetId);\n\t\t\t\tif (cs.kind === \"direct_edit\") {\n\t\t\t\t\tthrow new DirectEditRefusedError(\n\t\t\t\t\t\t\"one_branch\",\n\t\t\t\t\t\t`Change Set ${changeSetId} is a Direct Edit`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (cs.chains.some((chain) => chain.contentId === contentId)) {\n\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t`Content ${contentId} already has a Chain in this Change Set`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst label = Object.values(c.main.data)\n\t\t\t\t\t.filter((v): v is string => typeof v === \"string\")\n\t\t\t\t\t.slice(0, 2)\n\t\t\t\t\t.join(\" \");\n\t\t\t\tcs = {\n\t\t\t\t\tid: `cs_stub_${next++}`,\n\t\t\t\t\tname: changeSetName.trim()\n\t\t\t\t\t\t? oneLine(changeSetName, \"change_set_name\", CHANGE_SET_NAME_MAX)\n\t\t\t\t\t\t: label || contentId,\n\t\t\t\t\tstate: \"open\",\n\t\t\t\t\tcreatedBy: userId,\n\t\t\t\t\tcreateTime: now(),\n\t\t\t\t\tchains: [],\n\t\t\t\t\tdependsOnChangeSetIds: [],\n\t\t\t\t\tstatus: \"\",\n\t\t\t\t\tassigneeIds: [],\n\t\t\t\t\tplannedReleases: [],\n\t\t\t\t};\n\t\t\t\tchangeSets.unshift(cs);\n\t\t\t}\n\t\t\tconst n = next++;\n\t\t\tconst branchId = `br_stub_${n}`;\n\t\t\t// A Branch started on an existing Revision writes none.\n\t\t\tconst head = { ...structuredClone(c.main), branchId };\n\t\t\tc.branches[cs.id] = head;\n\t\t\tcs.chains.push({\n\t\t\t\tid: `chain_stub_${n}`,\n\t\t\t\tcontentId,\n\t\t\t\tborn: false,\n\t\t\t\tbranches: [\n\t\t\t\t\t{ id: branchId, position: 0, kind: \"editorial\", headRevisionId: head.revisionId },\n\t\t\t\t],\n\t\t\t});\n\t\t\tconst [content] = readsOf(c, { kind: \"change_set\", changeSetId: cs.id }, \"\");\n\t\t\treturn { changeSet: copy(cs), content };\n\t\t},\n\t\tasync previewChain({ changeSetId, contentId, effectiveOn, validityPeriod }) {\n\t\t\topen(changeSetId);\n\t\t\tconst c = findContent(contentId);\n\t\t\tif (!c.main) throw new InvalidInputError(`Content ${contentId} is not published`);\n\t\t\tif (!datedContent(c)) throw new InvalidInputError(\"undated Content's Chain takes no date\");\n\t\t\tif (!DAY.test(effectiveOn)) throw new InvalidInputError(\"effective_on is YYYY-MM-DD\");\n\t\t\tconst entries = c.timeline ?? [];\n\t\t\tconst fork = entries.find(\n\t\t\t\t(e) =>\n\t\t\t\t\te.validityPeriod &&\n\t\t\t\t\te.validityPeriod.firstDay <= effectiveOn &&\n\t\t\t\t\t(e.validityPeriod.lastDay === \"\" || effectiveOn <= e.validityPeriod.lastDay),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tforkReleaseId: fork?.releaseId ?? \"\",\n\t\t\t\tcarryForwardReleaseIds: entries\n\t\t\t\t\t.filter((e) => e.validityPeriod && e.validityPeriod.firstDay > effectiveOn)\n\t\t\t\t\t.map((e) => e.releaseId),\n\t\t\t\tmergesMain: false,\n\t\t\t\tcutIntoReleaseIds: fork ? [fork.releaseId] : [],\n\t\t\t\t// Only a period with a last day covers a Release: an open end\n\t\t\t\t// ends where the next Release starts.\n\t\t\t\tcoveredReleaseIds:\n\t\t\t\t\tvalidityPeriod && validityPeriod.lastDay !== \"\"\n\t\t\t\t\t\t? entries\n\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t(e) =>\n\t\t\t\t\t\t\t\t\t\te.validityPeriod &&\n\t\t\t\t\t\t\t\t\t\te.validityPeriod.lastDay !== \"\" &&\n\t\t\t\t\t\t\t\t\t\tvalidityPeriod.firstDay <= e.validityPeriod.firstDay &&\n\t\t\t\t\t\t\t\t\t\te.validityPeriod.lastDay <= validityPeriod.lastDay,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.map((e) => e.releaseId)\n\t\t\t\t\t\t: [],\n\t\t\t};\n\t\t},\n\t\tasync planRepeal({ changeSetId, contentId, lastDay }) {\n\t\t\topen(changeSetId);\n\t\t\tconst c = findContent(contentId);\n\t\t\tcheckEditable(c);\n\t\t\tif (!datedContent(c)) throw new InvalidInputError(\"a Repeal is for Dated Content\");\n\t\t\tif (!DAY.test(lastDay)) throw new InvalidInputError(\"last_day is YYYY-MM-DD\");\n\t\t\tconst inForce = releaseInForceOn(c.timeline ?? [], lastDay);\n\t\t\treturn plan(c, changeSetId, {\n\t\t\t\tkind: \"repeal\",\n\t\t\t\tvalidityPeriod: { firstDay: inForce?.validityPeriod?.firstDay ?? lastDay, lastDay },\n\t\t\t});\n\t\t},\n\t\tasync planWithdrawal({ changeSetId, contentId }) {\n\t\t\topen(changeSetId);\n\t\t\tconst c = findContent(contentId);\n\t\t\tcheckEditable(c);\n\t\t\tif (datedContent(c)) throw new InvalidInputError(\"a Withdrawal is for undated Content\");\n\t\t\treturn plan(c, changeSetId, { kind: \"withdrawal\" });\n\t\t},\n\n\t\tasync planRelease({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"planRelease\", request], async () => {\n\t\t\t\tconst { changeSetId, branchId, validityPeriod, releaseSpec, supersedesReleaseIds } =\n\t\t\t\t\trequest;\n\t\t\t\tconst { cs, chain, branch, c } = branchIn(changeSetId, branchId);\n\t\t\t\tcheckEditable(c);\n\t\t\t\tif (branch.kind !== \"editorial\") {\n\t\t\t\t\tthrow new InvalidInputError(\"only an editorial Branch's head is released\");\n\t\t\t\t}\n\t\t\t\tif (cs.plannedReleases.some((p) => p.branchId === branchId)) {\n\t\t\t\t\tthrow new InvalidInputError(`Branch ${branchId} is planned already`);\n\t\t\t\t}\n\t\t\t\tconst plan: PlannedRelease = {\n\t\t\t\t\tid: `rls_stub_${next++}`,\n\t\t\t\t\tcontentId: chain.contentId,\n\t\t\t\t\tkind: \"revision\",\n\t\t\t\t\tbranchId,\n\t\t\t\t\trevisionId: \"\",\n\t\t\t\t\tvalidityPeriod: validityPeriod ? { ...validityPeriod } : undefined,\n\t\t\t\t\treleaseSpec: structuredClone(releaseSpec ?? {}),\n\t\t\t\t\tsupersedesReleaseIds: [...(supersedesReleaseIds ?? [])],\n\t\t\t\t\tproposed: false,\n\t\t\t\t\tproposedForReleaseId: \"\",\n\t\t\t\t\tsplitFromReleaseId: \"\",\n\t\t\t\t\twithheld: false,\n\t\t\t\t};\n\t\t\t\tcheckPlan(c, plan);\n\t\t\t\tcs.plannedReleases.push(plan);\n\t\t\t\trepropose(cs, c);\n\t\t\t\treturn structuredClone(plan);\n\t\t\t});\n\t\t},\n\t\tasync updatePlannedRelease({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"updatePlannedRelease\", request], async () => {\n\t\t\t\tconst { changeSetId, plannedReleaseId, validityPeriod, releaseSpec, supersedesReleaseIds } =\n\t\t\t\t\trequest;\n\t\t\t\tconst cs = open(changeSetId);\n\t\t\t\tconst at = cs.plannedReleases.findIndex((p) => p.id === plannedReleaseId);\n\t\t\t\tif (at < 0) throw notFound(\"Planned Release\", plannedReleaseId);\n\t\t\t\tconst current = cs.plannedReleases[at];\n\t\t\t\tif (current.proposed) {\n\t\t\t\t\tthrow new InvalidInputError(\"a proposal is derived from the plans and can't be set\");\n\t\t\t\t}\n\t\t\t\tconst c = findContent(current.contentId);\n\t\t\t\tcheckEditable(c);\n\t\t\t\tconst updated: PlannedRelease = {\n\t\t\t\t\t...structuredClone(current),\n\t\t\t\t\t...(validityPeriod ? { validityPeriod: { ...validityPeriod } } : {}),\n\t\t\t\t\t...(releaseSpec ? { releaseSpec: structuredClone(releaseSpec) } : {}),\n\t\t\t\t\t...(supersedesReleaseIds ? { supersedesReleaseIds: [...supersedesReleaseIds] } : {}),\n\t\t\t\t};\n\t\t\t\tcheckPlan(c, updated);\n\t\t\t\tcs.plannedReleases[at] = updated;\n\t\t\t\trepropose(cs, c);\n\t\t\t\treturn structuredClone(updated);\n\t\t\t});\n\t\t},\n\t\tasync appendBranch({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"appendBranch\", request], async () => {\n\t\t\t\tconst { changeSetId, chainId, effectiveOn } = request;\n\t\t\t\tconst cs = open(changeSetId);\n\t\t\t\tconst chain = cs.chains.find((ch) => ch.id === chainId);\n\t\t\t\tif (!chain) throw notFound(\"Chain\", chainId);\n\t\t\t\tconst c = findContent(chain.contentId);\n\t\t\t\tif (chain.born || !datedContent(c)) {\n\t\t\t\t\tthrow new InvalidInputError(\"only a Chain on published Dated Content takes dates\");\n\t\t\t\t}\n\t\t\t\tconst last = chain.branches.filter((b) => b.kind === \"editorial\").at(-1);\n\t\t\t\tif (!DAY.test(effectiveOn) || (last?.effectiveOn && effectiveOn <= last.effectiveOn)) {\n\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t\"effective_on is a day after the Chain's last editorial Branch's\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst tip = chain.branches.at(-1);\n\t\t\t\tconst n = next++;\n\t\t\t\tconst branchId = `br_stub_${n}`;\n\t\t\t\tchain.branches.push({\n\t\t\t\t\tid: branchId,\n\t\t\t\t\tposition: chain.branches.length,\n\t\t\t\t\tkind: \"editorial\",\n\t\t\t\t\t// A Branch starts at the head of the one before: no Revision written.\n\t\t\t\t\theadRevisionId: tip?.headRevisionId ?? \"\",\n\t\t\t\t\teffectiveOn,\n\t\t\t\t});\n\t\t\t\tconst head = c.branches[changeSetId];\n\t\t\t\tif (head) c.branches[changeSetId] = { ...head, branchId };\n\t\t\t\treturn { changeSet: copy(cs), branchId };\n\t\t\t});\n\t\t},\n\t\tasync dropChain({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"dropChain\", request], async () => {\n\t\t\t\tconst { changeSetId, chainId } = request;\n\t\t\t\tconst cs = open(changeSetId);\n\t\t\t\tconst chain = cs.chains.find((ch) => ch.id === chainId);\n\t\t\t\tif (!chain) throw notFound(\"Chain\", chainId);\n\t\t\t\tif (chain.born) {\n\t\t\t\t\tthrow new InvalidInputError(\n\t\t\t\t\t\t\"the Chain of Content born in the Change Set can't be dropped: discard the Change Set\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tfor (const b of chain.branches) dropMerge(b.id);\n\t\t\t\tcs.chains = cs.chains.filter((ch) => ch.id !== chainId);\n\t\t\t\tcs.plannedReleases = cs.plannedReleases.filter((p) => p.contentId !== chain.contentId);\n\t\t\t\tdelete findContent(chain.contentId).branches[changeSetId];\n\t\t\t\treturn copy(cs);\n\t\t\t});\n\t\t},\n\t\tasync getPendingMerge(branchId) {\n\t\t\tconst pm = stored.get(branchId);\n\t\t\treturn pm ? structuredClone(pm) : null;\n\t\t},\n\t\tasync resolveMerge({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"resolveMerge\", request], async () => {\n\t\t\t\tconst { changeSetId, branchId, expectedHeadId, resolutions } = request;\n\t\t\t\tconst { chain, branch, c } = branchIn(changeSetId, branchId);\n\t\t\t\tconst pm = stored.get(branchId);\n\t\t\t\tif (!pm) throw new InvalidInputError(`Branch ${branchId} has no Pending Merge`);\n\t\t\t\tif (branch.headRevisionId !== expectedHeadId) {\n\t\t\t\t\tthrow new StaleHeadError({\n\t\t\t\t\t\tcontentId: c.id,\n\t\t\t\t\t\tbranchId,\n\t\t\t\t\t\texpectedHeadId,\n\t\t\t\t\t\tcurrentHeadId: branch.headRevisionId,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst paths = resolutions.map((r) => r.path);\n\t\t\t\tconst listed = pm.fields.map((f) => f.path);\n\t\t\t\tif (\n\t\t\t\t\tnew Set(paths).size !== paths.length ||\n\t\t\t\t\tpaths.some((p) => !listed.includes(p)) ||\n\t\t\t\t\tlisted.some((p) => !paths.includes(p))\n\t\t\t\t) {\n\t\t\t\t\tthrow new InvalidInputError(\"decide every field the Pending Merge lists, once\");\n\t\t\t\t}\n\t\t\t\tconst data = structuredClone(pm.merged);\n\t\t\t\tfor (const r of resolutions) {\n\t\t\t\t\tconst f = pm.fields.find((each) => each.path === r.path) as MergeField;\n\t\t\t\t\tconst value = \"side\" in r ? (r.side === \"ours\" ? f.ours : f.theirs) : r.value;\n\t\t\t\t\tconst key = r.path.replace(/^\\//, \"\");\n\t\t\t\t\tif (value === undefined) delete data[key];\n\t\t\t\t\telse data[key] = structuredClone(value);\n\t\t\t\t}\n\t\t\t\tconst content = writeHead({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tchain,\n\t\t\t\t\tbranch,\n\t\t\t\t\tc,\n\t\t\t\t\tdata,\n\t\t\t\t\tcause: \"resolve\",\n\t\t\t\t\tsecondParentId: pm.theirsRevisionId,\n\t\t\t\t});\n\t\t\t\tdropMerge(branchId);\n\t\t\t\t// Resolved, the Branch has taken in its base.\n\t\t\t\tbehind.delete(branchId);\n\t\t\t\treturn content;\n\t\t\t});\n\t\t},\n\t\tasync abortMerge({ idempotencyKey, ...request }) {\n\t\t\treturn once(idempotencyKey, [\"abortMerge\", request], async () => {\n\t\t\t\tbranchIn(request.changeSetId, request.branchId);\n\t\t\t\tif (!stored.has(request.branchId)) {\n\t\t\t\t\tthrow new InvalidInputError(`Branch ${request.branchId} has no Pending Merge`);\n\t\t\t\t}\n\t\t\t\tdropMerge(request.branchId);\n\t\t\t});\n\t\t},\n\t\tasync previewInForce({ contentId, changeSetId, validOn }) {\n\t\t\tconst cs = open(changeSetId);\n\t\t\tconst c = findContent(contentId);\n\t\t\tconst day = validOn || today();\n\t\t\tconst chain = cs.chains.find((ch) => ch.contentId === contentId);\n\t\t\tconst covers = (p: PlannedRelease) =>\n\t\t\t\t!p.validityPeriod ||\n\t\t\t\t(p.validityPeriod.firstDay <= day &&\n\t\t\t\t\t(p.validityPeriod.lastDay === \"\" || day <= p.validityPeriod.lastDay));\n\t\t\t// The Change Set's own plans first, read as if published now.\n\t\t\tconst plan = cs.plannedReleases.find(\n\t\t\t\t(p) => p.contentId === contentId && p.kind !== \"repeal\" && covers(p),\n\t\t\t);\n\t\t\tif (plan) {\n\t\t\t\tconst revisionId = plan.branchId\n\t\t\t\t\t? (chain?.branches.find((b) => b.id === plan.branchId)?.headRevisionId ?? \"\")\n\t\t\t\t\t: plan.revisionId;\n\t\t\t\treturn {\n\t\t\t\t\treleaseId: plan.id,\n\t\t\t\t\trevisionId,\n\t\t\t\t\tplanned: true,\n\t\t\t\t\twithheld: false,\n\t\t\t\t\tvalidityPeriod: plan.validityPeriod ? { ...plan.validityPeriod } : undefined,\n\t\t\t\t\tdata: structuredClone(dataOf(c, revisionId) ?? {}),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst entry = releaseInForceOn(c.timeline ?? [], day);\n\t\t\tif (!entry) return null;\n\t\t\treturn {\n\t\t\t\treleaseId: entry.releaseId,\n\t\t\t\trevisionId: entry.revisionId,\n\t\t\t\tplanned: false,\n\t\t\t\twithheld: false,\n\t\t\t\tvalidityPeriod: entry.validityPeriod ? { ...entry.validityPeriod } : undefined,\n\t\t\t\tdata: structuredClone(dataOf(c, entry.revisionId) ?? {}),\n\t\t\t};\n\t\t},\n\t};\n\treturn client;\n\n\t/** Plans a Release ending a Content's force in a Change Set, warning of the gap it leaves. */\n\tfunction plan(\n\t\tc: StubContent,\n\t\tchangeSetId: string,\n\t\twhat: Pick<PlannedEnd[\"plannedRelease\"], \"kind\" | \"validityPeriod\">,\n\t): PlannedEnd {\n\t\tconst plannedRelease = {\n\t\t\tid: `rls_stub_${next++}`,\n\t\t\tcontentId: c.id,\n\t\t\tbranchId: \"\",\n\t\t\t// A Repeal or Withdrawal re-pins the Revision In Force.\n\t\t\trevisionId: c.inForce?.revisionId ?? c.main?.revisionId ?? \"\",\n\t\t\tsupersedesReleaseIds: [],\n\t\t\tproposed: false,\n\t\t\tproposedForReleaseId: \"\",\n\t\t\tsplitFromReleaseId: \"\",\n\t\t\twithheld: false,\n\t\t\t...what,\n\t\t};\n\t\tc.plannedReleases = [...(c.plannedReleases ?? []), { changeSetId, plannedRelease }];\n\t\treturn structuredClone({ plannedRelease, gapReferrers: gapReferrersOf(c.id) });\n\t}\n\n\t/**\n\t * Every row one Content gives in a view: its Main head on Main, its\n\t * Release on In Force, its head in a Change Set there. A search on Main\n\t * also reads every open Branch head, one row per head that matched, as\n\t * Editor Search does (ADR 0019).\n\t */\n\tfunction readsOf(c: StubContent, view: ContentView, search: string): Content[] {\n\t\tconst row = (\n\t\t\thead: { revisionId: string; data: Record<string, unknown>; revisionCreateTime: string },\n\t\t\tat: { changeSetId?: string; branchId?: string; releaseId?: string },\n\t\t): Content => ({\n\t\t\tid: c.id,\n\t\t\tblueprintId: c.blueprintId,\n\t\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\t\trevisionId: head.revisionId,\n\t\t\tdata: structuredClone(head.data),\n\t\t\tchangeSetId: at.changeSetId ?? \"\",\n\t\t\tbranchId: at.branchId ?? \"\",\n\t\t\trevisionCreateTime: head.revisionCreateTime,\n\t\t\treleaseId: at.releaseId ?? \"\",\n\t\t});\n\t\tif (view.kind === \"in_force\") {\n\t\t\treturn c.inForce ? [row(c.inForce, { releaseId: c.inForce.releaseId })] : [];\n\t\t}\n\t\tif (view.kind === \"change_set\") {\n\t\t\tconst head = c.branches[view.changeSetId];\n\t\t\tif (!head || (search && !matches(head.data, search))) return [];\n\t\t\treturn [row(head, { changeSetId: view.changeSetId, branchId: head.branchId })];\n\t\t}\n\t\tif (!search) return c.main ? [row(c.main, {})] : [];\n\t\tconst hits: Content[] = [];\n\t\tif (c.main && matches(c.main.data, search)) hits.push(row(c.main, {}));\n\t\tfor (const [csId, head] of Object.entries(c.branches).sort(([, a], [, b]) =>\n\t\t\ta.branchId < b.branchId ? -1 : 1,\n\t\t)) {\n\t\t\tconst inOpen = changeSets.find((cs) => cs.id === csId)?.state === \"open\";\n\t\t\tif (inOpen && matches(head.data, search)) {\n\t\t\t\thits.push(row(head, { changeSetId: csId, branchId: head.branchId }));\n\t\t\t}\n\t\t}\n\t\treturn hits;\n\t}\n}\n\n/** Editor Search's match: within one field, ignoring case, any run of whitespace for any run. */\nfunction matches(data: Record<string, unknown>, search: string): boolean {\n\tconst fold = (s: string) => s.toLocaleLowerCase().replace(/\\s+/g, \" \");\n\tconst needle = fold(search);\n\treturn Object.values(data).some((v) => typeof v === \"string\" && fold(v).includes(needle));\n}\n","// A `StatusSource` over a fixed catalogue: the port a host fills with\n// statushub (ADR 0020), stubbed so a host's tests need no statushub.\nimport type { ChangeSetStatusInfo, StatusSource } from \"../types\";\nimport { stubChangeSetStatuses } from \"./fixtures\";\n\nexport function createStubStatusSource(\n\tstatuses: ChangeSetStatusInfo[] = stubChangeSetStatuses(),\n): StatusSource {\n\treturn {\n\t\tasync listChangeSetStatuses() {\n\t\t\treturn statuses.map((s) => ({ ...s }));\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|