@knpkv/control-center 0.1.0 → 0.2.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/dist/client/.vite/manifest.json +127 -125
- package/dist/client/assets/{ActiveWorkPage-Bvji6Tys.js → ActiveWorkPage-C6QwDV1Y.js} +2 -2
- package/dist/client/assets/{ActiveWorkPage-Bvji6Tys.js.map → ActiveWorkPage-C6QwDV1Y.js.map} +1 -1
- package/dist/client/assets/{AgentPage-Bom41la2.js → AgentPage-OqwP6uRi.js} +2 -2
- package/dist/client/assets/{AgentPage-Bom41la2.js.map → AgentPage-OqwP6uRi.js.map} +1 -1
- package/dist/client/assets/{AtlassianOAuthCallbackPage-dr-B9-DD.js → AtlassianOAuthCallbackPage-Bm7UhU-h.js} +2 -2
- package/dist/client/assets/{AtlassianOAuthCallbackPage-dr-B9-DD.js.map → AtlassianOAuthCallbackPage-Bm7UhU-h.js.map} +1 -1
- package/dist/client/assets/{AuthorizedSharePage-C-P-PNfm.js → AuthorizedSharePage-DblP3USU.js} +2 -2
- package/dist/client/assets/{AuthorizedSharePage-C-P-PNfm.js.map → AuthorizedSharePage-DblP3USU.js.map} +1 -1
- package/dist/client/assets/{BrowserCrypto-BPiuCuW-.js → BrowserCrypto-BGGRC6iW.js} +2 -2
- package/dist/client/assets/{BrowserCrypto-BPiuCuW-.js.map → BrowserCrypto-BGGRC6iW.js.map} +1 -1
- package/dist/client/assets/{BrowserSessionHydrator-C8F_LGhg.js → BrowserSessionHydrator-39UDbHf0.js} +2 -2
- package/dist/client/assets/{BrowserSessionHydrator-C8F_LGhg.js.map → BrowserSessionHydrator-39UDbHf0.js.map} +1 -1
- package/dist/client/assets/{CommandSearch-D6iFcdvj.js → CommandSearch-D4Fnjsl-.js} +2 -2
- package/dist/client/assets/{CommandSearch-D6iFcdvj.js.map → CommandSearch-D4Fnjsl-.js.map} +1 -1
- package/dist/client/assets/{ItemsPage-x39U11an.js → ItemsPage-BZQiTh9b.js} +2 -2
- package/dist/client/assets/{ItemsPage-x39U11an.js.map → ItemsPage-BZQiTh9b.js.map} +1 -1
- package/dist/client/assets/{PairPage-D5vlz4OG.js → PairPage-Dvfse5ky.js} +2 -2
- package/dist/client/assets/{PairPage-D5vlz4OG.js.map → PairPage-Dvfse5ky.js.map} +1 -1
- package/dist/client/assets/{PortfolioOverview-DSUabOmm.js → PortfolioOverview-DeJcfXcw.js} +2 -2
- package/dist/client/assets/{PortfolioOverview-DSUabOmm.js.map → PortfolioOverview-DeJcfXcw.js.map} +1 -1
- package/dist/client/assets/{ReleaseRoute-DyDm5s85.js → ReleaseRoute-D9q8_sCk.js} +2 -2
- package/dist/client/assets/{ReleaseRoute-DyDm5s85.js.map → ReleaseRoute-D9q8_sCk.js.map} +1 -1
- package/dist/client/assets/ReleaseWorkset-Bs_FXlbC.js +2 -0
- package/dist/client/assets/ReleaseWorkset-Bs_FXlbC.js.map +1 -0
- package/dist/client/assets/{ServicesPage-CoMVH2Si.js → ServicesPage-Co6GJHgc.js} +2 -2
- package/dist/client/assets/{ServicesPage-CoMVH2Si.js.map → ServicesPage-Co6GJHgc.js.map} +1 -1
- package/dist/client/assets/{TimelinePage-D8Fj_351.js → TimelinePage-CM2og72M.js} +2 -2
- package/dist/client/assets/{TimelinePage-D8Fj_351.js.map → TimelinePage-CM2og72M.js.map} +1 -1
- package/dist/client/assets/{WorkspaceEntityLink-BRifdJHn.js → WorkspaceEntityLink-CTw_He-8.js} +2 -2
- package/dist/client/assets/{WorkspaceEntityLink-BRifdJHn.js.map → WorkspaceEntityLink-CTw_He-8.js.map} +1 -1
- package/dist/client/assets/{WorkspaceEntityRoute-BwpujSqk.css → WorkspaceEntityRoute-Bdmv6ki4.css} +1 -1
- package/dist/client/assets/WorkspaceEntityRoute-BnsmaeS2.js +30 -0
- package/dist/client/assets/WorkspaceEntityRoute-BnsmaeS2.js.map +1 -0
- package/dist/client/assets/{WorkspaceReleaseLayout-DDLdY0rU.js → WorkspaceReleaseLayout-Ba6keUju.js} +2 -2
- package/dist/client/assets/{WorkspaceReleaseLayout-DDLdY0rU.js.map → WorkspaceReleaseLayout-Ba6keUju.js.map} +1 -1
- package/dist/client/assets/{authenticatedMutationClient-D5yD0rch.js → authenticatedMutationClient-CJklf3iD.js} +2 -2
- package/dist/client/assets/{authenticatedMutationClient-D5yD0rch.js.map → authenticatedMutationClient-CJklf3iD.js.map} +1 -1
- package/dist/client/assets/{authorizedShareTransport-Dyj53kJf.js → authorizedShareTransport-Xg20SHJ5.js} +2 -2
- package/dist/client/assets/{authorizedShareTransport-Dyj53kJf.js.map → authorizedShareTransport-Xg20SHJ5.js.map} +1 -1
- package/dist/client/assets/{client-OmvShYdC.js → client-P7FaPwzJ.js} +2 -2
- package/dist/client/assets/{client-OmvShYdC.js.map → client-P7FaPwzJ.js.map} +1 -1
- package/dist/client/assets/{connectionTestTransport-c25QXx7A.js → connectionTestTransport-C9iPOkKM.js} +2 -2
- package/dist/client/assets/{connectionTestTransport-c25QXx7A.js.map → connectionTestTransport-C9iPOkKM.js.map} +1 -1
- package/dist/client/assets/{index-DLoOV6Hp.js → index-DpW_ckau.js} +3 -3
- package/dist/client/assets/{index-DLoOV6Hp.js.map → index-DpW_ckau.js.map} +1 -1
- package/dist/client/assets/{patterns-DEbg7R-A-Cw0A2uKS.js → patterns-DEbg7R-A-BhsMyh9D.js} +2 -2
- package/dist/client/assets/{patterns-DEbg7R-A-Cw0A2uKS.js.map → patterns-DEbg7R-A-BhsMyh9D.js.map} +1 -1
- package/dist/client/assets/{presentPortfolio-CkRqd_zz.js → presentPortfolio-D-v615bg.js} +2 -2
- package/dist/client/assets/{presentPortfolio-CkRqd_zz.js.map → presentPortfolio-D-v615bg.js.map} +1 -1
- package/dist/client/assets/presentWorkspaceItems-IAp5SnpB.js +2 -0
- package/dist/client/assets/presentWorkspaceItems-IAp5SnpB.js.map +1 -0
- package/dist/client/assets/{releaseRoutes-DSWkTh-E.js → releaseRoutes-CfaNElmG.js} +2 -2
- package/dist/client/assets/{releaseRoutes-DSWkTh-E.js.map → releaseRoutes-CfaNElmG.js.map} +1 -1
- package/dist/client/assets/{serviceOnboarding-B9pvdyWf.js → serviceOnboarding-BZ2U_Ugw.js} +2 -2
- package/dist/client/assets/{serviceOnboarding-B9pvdyWf.js.map → serviceOnboarding-BZ2U_Ugw.js.map} +1 -1
- package/dist/client/assets/{useWorkspaceItems-D0FuHGto.js → useWorkspaceItems-DQTYaq1R.js} +2 -2
- package/dist/client/assets/{useWorkspaceItems-D0FuHGto.js.map → useWorkspaceItems-DQTYaq1R.js.map} +1 -1
- package/dist/client/assets/workspaceEntityRoutes-Biw67kRR.js +2 -0
- package/dist/client/assets/workspaceEntityRoutes-Biw67kRR.js.map +1 -0
- package/dist/client/build-graph.json +32 -2
- package/dist/client/index.html +1 -1
- package/dist/server/api/deliveryGraph.d.ts +126 -0
- package/dist/server/api/deliveryGraph.d.ts.map +1 -1
- package/dist/server/api/index.js +2 -2
- package/dist/server/api/shares.d.ts +14 -0
- package/dist/server/api/shares.d.ts.map +1 -1
- package/dist/server/assets/{BindConfig-BjK10BEb.js → BindConfig-Dk3vjYZc.js} +7 -7
- package/dist/server/assets/{BindConfig-BjK10BEb.js.map → BindConfig-Dk3vjYZc.js.map} +1 -1
- package/dist/server/assets/{controlCenterApi-tZPvRPRH.js → controlCenterApi-Dsug4Rzi.js} +2 -2
- package/dist/server/assets/{controlCenterApi-tZPvRPRH.js.map → controlCenterApi-Dsug4Rzi.js.map} +1 -1
- package/dist/server/assets/{domainEvent-x7yeq-gU.js → domainEvent-CZLKMqgn.js} +13 -2
- package/dist/server/assets/{domainEvent-x7yeq-gU.js.map → domainEvent-CZLKMqgn.js.map} +1 -1
- package/dist/server/assets/{firstPartyServices-Y41P8uke.js → firstPartyServices-BWdrzdfD.js} +2 -2
- package/dist/server/assets/{firstPartyServices-Y41P8uke.js.map → firstPartyServices-BWdrzdfD.js.map} +1 -1
- package/dist/server/assets/{manualPluginSynchronization-C0aHB4UM.js → manualPluginSynchronization-CDnX9qXi.js} +64 -23
- package/dist/server/assets/manualPluginSynchronization-CDnX9qXi.js.map +1 -0
- package/dist/server/assets/{portfolioInvalidation-Ds9Xm4_P.js → portfolioInvalidation-iTUo5N4r.js} +26 -6
- package/dist/server/assets/portfolioInvalidation-iTUo5N4r.js.map +1 -0
- package/dist/server/assets/{readiness-CzU3vjYQ.js → readiness-CZBkcjLP.js} +2 -2
- package/dist/server/assets/{readiness-CzU3vjYQ.js.map → readiness-CZBkcjLP.js.map} +1 -1
- package/dist/server/build-graph.json +1 -0
- package/dist/server/domain/deliveryGraph.d.ts +14 -0
- package/dist/server/domain/deliveryGraph.d.ts.map +1 -1
- package/dist/server/domain/index.js +3 -3
- package/dist/server/index.js +4 -4
- package/dist/server/server/application/normalizedPluginPageMaterialization.d.ts +1 -1
- package/dist/server/server/application/normalizedPluginPageMaterialization.d.ts.map +1 -1
- package/dist/server/server/cli.js +4 -4
- package/dist/server/server/index.js +3 -3
- package/dist/server/server/persistence/Persistence.d.ts +35 -0
- package/dist/server/server/persistence/Persistence.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/contract.d.ts +56 -0
- package/dist/server/server/persistence/repositories/delivery-graph/contract.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/decode.d.ts +7 -0
- package/dist/server/server/persistence/repositories/delivery-graph/decode.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/read.d.ts +35 -0
- package/dist/server/server/persistence/repositories/delivery-graph/read.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/rows.d.ts +7 -0
- package/dist/server/server/persistence/repositories/delivery-graph/rows.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/write.d.ts +14 -0
- package/dist/server/server/persistence/repositories/delivery-graph/write.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/deliveryGraphRepository.d.ts +35 -0
- package/dist/server/server/persistence/repositories/deliveryGraphRepository.d.ts.map +1 -1
- package/package.json +6 -6
- package/dist/client/assets/ReleaseWorkset-BhGacsgb.js +0 -2
- package/dist/client/assets/ReleaseWorkset-BhGacsgb.js.map +0 -1
- package/dist/client/assets/WorkspaceEntityRoute-DPci8Q8I.js +0 -30
- package/dist/client/assets/WorkspaceEntityRoute-DPci8Q8I.js.map +0 -1
- package/dist/client/assets/presentWorkspaceItems-BU__8LcC.js +0 -2
- package/dist/client/assets/presentWorkspaceItems-BU__8LcC.js.map +0 -1
- package/dist/client/assets/workspaceEntityRoutes-CRcfSq7c.js +0 -2
- package/dist/client/assets/workspaceEntityRoutes-CRcfSq7c.js.map +0 -1
- package/dist/server/assets/manualPluginSynchronization-C0aHB4UM.js.map +0 -1
- package/dist/server/assets/portfolioInvalidation-Ds9Xm4_P.js.map +0 -1
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{K as e}from"./client-OmvShYdC.js";import{n as t}from"./workspaceEntityPaths-xAl2jRFm.js";var n=e=>{switch(e){case`change-owner`:case`issue-owner`:case`page-owner`:return`Owner`;case`issue-assignee`:return`Assignee`;case`author`:return`Author`;case`operator`:return`Operator`;default:return i(e)}},r=e=>{switch(e){case`issue`:return`jira`;case`pull-request`:return`codecommit`;case`page`:return`confluence`;case`pipeline-execution`:case`deployment`:return`codepipeline`;case`time-entry`:return`clockify`}},i=e=>e.split(`-`).map(e=>`${e.charAt(0).toLocaleUpperCase(`en-US`)}${e.slice(1)}`).join(` `),a=e=>{switch(e._tag){case`issue`:return e.status;case`pull-request`:return i(e.reviewState);case`page`:case`pipeline-execution`:case`deployment`:return i(e.status);case`time-entry`:return i(e.approvalState)}},o=e=>{let t=e.trim().toLocaleLowerCase(`en-US`);return t===`blocked`||t===`rejected`?{statusGroup:`failed`,tone:`critical`}:t===`closed`||t===`done`||t===`resolved`?{statusGroup:`done`,tone:`positive`}:{statusGroup:`active`,tone:`progress`}},s=(e,t)=>{if(e===`issue`)return o(t);let n=t.toLocaleLowerCase(`en-US`);return[`blocked`,`changes requested`,`failed`,`rejected`,`rolled back`,`stopped`,`superseded`].some(e=>n.includes(e))?{statusGroup:`failed`,tone:`critical`}:[`approved`,`closed`,`current`,`done`,`merged`,`not required`,`ready`,`resolved`,`succeeded`].some(e=>n.includes(e))?{statusGroup:`done`,tone:`positive`}:{statusGroup:`active`,tone:`progress`}},c=(e,t,n)=>`/w/${e}/releases/${t}?object=${encodeURIComponent(n)}#release-work`,l=(i,o,c)=>{let l=o.projection,u=a(l.details),d=o.releaseIds.filter(e=>c===void 0||c.has(e)),f=o.releaseIds.length===1&&!o.releaseMembershipsTruncated?d[0]??null:null,p=(o.owners??[]).map(({avatarFallback:e,displayName:t,personId:r,roles:i})=>({avatarFallback:e,id:r,name:t,role:[...new Set(i.map(n))].join(` · `),roles:i}));return{entityId:l.entityId,freshness:e(o.recordedAt),href:t(i,l.entityId),key:l.displayKey,kind:l.entityType,owner:p.length===0?`Unassigned`:p.map(({name:e})=>e).join(`, `),owners:p,ownersTruncated:o.ownersTruncated??!1,releaseId:f,releaseIds:o.releaseIds,releaseMembershipsTruncated:o.releaseMembershipsTruncated,routableReleaseIds:d,service:r(l.entityType),status:u,...s(l.entityType,u),title:l.title}},u=(e,t,n)=>t.items.filter(({projection:e})=>e.entityState===`present`).map(t=>l(e,t,n)).sort((e,t)=>e.service.localeCompare(t.service)||e.key.localeCompare(t.key));export{c as a,s as i,r as n,a as r,u as t};
|
|
2
|
-
//# sourceMappingURL=presentWorkspaceItems-BU__8LcC.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"presentWorkspaceItems-BU__8LcC.js","names":[],"sources":["../../../src/client/items/presentWorkspaceItems.ts"],"sourcesContent":["import type { RlyService } from \"@knpkv/rly/patterns\"\nimport type { RlyStateTone } from \"@knpkv/rly/primitives\"\nimport * as DateTime from \"effect/DateTime\"\n\nimport type {\n ReleaseDeliveryGraphInspection,\n WorkspaceEntityOwner,\n WorkspaceEntityProjectionIndex\n} from \"../../api/deliveryGraph.js\"\nimport type { Role } from \"../../domain/actors.js\"\nimport type {\n DeliveryEntityDetails,\n DeliveryEntityKind,\n DeliveryEntityStatusGroup\n} from \"../../domain/deliveryGraph.js\"\nimport type { EntityId, ReleaseId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport { workspaceEntityPath } from \"../workspaceEntityPaths.js\"\n\nexport type WorkspaceItemStatus = DeliveryEntityStatusGroup\n\nexport interface WorkspaceItemPresentation {\n readonly entityId: EntityId\n readonly freshness: string\n readonly href: string\n readonly key: string\n readonly kind: DeliveryEntityKind\n readonly owner: string\n readonly owners: ReadonlyArray<WorkspaceItemOwnerPresentation>\n readonly ownersTruncated: boolean\n readonly releaseId: ReleaseId | null\n readonly releaseIds: ReadonlyArray<ReleaseId>\n readonly releaseMembershipsTruncated: boolean\n readonly routableReleaseIds: ReadonlyArray<ReleaseId>\n readonly service: RlyService\n readonly status: string\n readonly statusGroup: WorkspaceItemStatus\n readonly title: string\n readonly tone: RlyStateTone\n}\n\nexport interface WorkspaceItemOwnerPresentation {\n readonly avatarFallback: string\n readonly id: string\n readonly name: string\n readonly role: string\n readonly roles: ReadonlyArray<Role>\n}\n\nconst collaboratorRoleLabel = (role: Role): string => {\n switch (role) {\n case \"change-owner\":\n case \"issue-owner\":\n case \"page-owner\":\n return \"Owner\"\n case \"issue-assignee\":\n return \"Assignee\"\n case \"author\":\n return \"Author\"\n case \"operator\":\n return \"Operator\"\n default:\n return titleCase(role)\n }\n}\n\nexport const serviceFor = (kind: DeliveryEntityKind): RlyService => {\n switch (kind) {\n case \"issue\":\n return \"jira\"\n case \"pull-request\":\n return \"codecommit\"\n case \"page\":\n return \"confluence\"\n case \"pipeline-execution\":\n case \"deployment\":\n return \"codepipeline\"\n case \"time-entry\":\n return \"clockify\"\n }\n}\n\nconst titleCase = (value: string): string =>\n value.split(\"-\").map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`).join(\" \")\n\nexport const statusFor = (details: DeliveryEntityDetails): string => {\n switch (details._tag) {\n case \"issue\":\n return details.status\n case \"pull-request\":\n return titleCase(details.reviewState)\n case \"page\":\n case \"pipeline-execution\":\n case \"deployment\":\n return titleCase(details.status)\n case \"time-entry\":\n return titleCase(details.approvalState)\n }\n}\n\nconst issueStatusPresentation = (status: string): Pick<WorkspaceItemPresentation, \"statusGroup\" | \"tone\"> => {\n const value = status.trim().toLocaleLowerCase(\"en-US\")\n if (value === \"blocked\" || value === \"rejected\") return { statusGroup: \"failed\", tone: \"critical\" }\n if (value === \"closed\" || value === \"done\" || value === \"resolved\") {\n return { statusGroup: \"done\", tone: \"positive\" }\n }\n return { statusGroup: \"active\", tone: \"progress\" }\n}\n\nexport const statusPresentation = (\n kind: DeliveryEntityKind,\n status: string\n): Pick<WorkspaceItemPresentation, \"statusGroup\" | \"tone\"> => {\n if (kind === \"issue\") return issueStatusPresentation(status)\n const value = status.toLocaleLowerCase(\"en-US\")\n if (\n [\"blocked\", \"changes requested\", \"failed\", \"rejected\", \"rolled back\", \"stopped\", \"superseded\"].some((part) =>\n value.includes(part)\n )\n ) return { statusGroup: \"failed\", tone: \"critical\" }\n if (\n [\"approved\", \"closed\", \"current\", \"done\", \"merged\", \"not required\", \"ready\", \"resolved\", \"succeeded\"]\n .some((part) => value.includes(part))\n ) return { statusGroup: \"done\", tone: \"positive\" }\n return { statusGroup: \"active\", tone: \"progress\" }\n}\n\nexport const workspaceItemReleaseHref = (\n workspaceId: WorkspaceId,\n releaseId: ReleaseId,\n entityId: EntityId\n): string => `/w/${workspaceId}/releases/${releaseId}?object=${encodeURIComponent(entityId)}#release-work`\n\nconst presentProjection = (\n workspaceId: WorkspaceId,\n entry: ReleaseDeliveryGraphInspection[\"entityProjections\"][number] & {\n readonly canonicalReleaseId: ReleaseId | null\n readonly owners?: ReadonlyArray<WorkspaceEntityOwner>\n readonly ownersTruncated?: boolean\n readonly releaseIds: ReadonlyArray<ReleaseId>\n readonly releaseMembershipsTruncated: boolean\n },\n routableReleaseIds?: ReadonlySet<ReleaseId>\n): WorkspaceItemPresentation => {\n const projection = entry.projection\n const status = statusFor(projection.details)\n const routableMemberships = entry.releaseIds.filter(\n (releaseId) => routableReleaseIds === undefined || routableReleaseIds.has(releaseId)\n )\n const releaseId = entry.releaseIds.length === 1 && !entry.releaseMembershipsTruncated\n ? (routableMemberships[0] ?? null)\n : null\n const owners: ReadonlyArray<WorkspaceItemOwnerPresentation> = (entry.owners ?? []).map(({\n avatarFallback,\n displayName,\n personId,\n roles\n }) => ({\n avatarFallback,\n id: personId,\n name: displayName,\n role: [...new Set(roles.map(collaboratorRoleLabel))].join(\" · \"),\n roles\n }))\n return {\n entityId: projection.entityId,\n freshness: DateTime.formatIso(entry.recordedAt),\n href: workspaceEntityPath(workspaceId, projection.entityId),\n key: projection.displayKey,\n kind: projection.entityType,\n owner: owners.length === 0 ? \"Unassigned\" : owners.map(({ name }) => name).join(\", \"),\n owners,\n ownersTruncated: entry.ownersTruncated ?? false,\n releaseId,\n releaseIds: entry.releaseIds,\n releaseMembershipsTruncated: entry.releaseMembershipsTruncated,\n routableReleaseIds: routableMemberships,\n service: serviceFor(projection.entityType),\n status,\n ...statusPresentation(projection.entityType, status),\n title: projection.title\n }\n}\n\n/** Present one server-authoritative workspace entity index. */\nexport const presentWorkspaceEntityIndex = (\n workspaceId: WorkspaceId,\n index: WorkspaceEntityProjectionIndex,\n routableReleaseIds?: ReadonlySet<ReleaseId>\n): ReadonlyArray<WorkspaceItemPresentation> =>\n index.items\n .filter(({ projection }) => projection.entityState === \"present\")\n .map((entry) => presentProjection(workspaceId, entry, routableReleaseIds))\n .sort((left, right) => left.service.localeCompare(right.service) || left.key.localeCompare(right.key))\n\n/** Present bounded release slices as one deduplicated release-linked item index. */\nexport const presentWorkspaceItems = (\n workspaceId: WorkspaceId,\n inspections: ReadonlyArray<ReleaseDeliveryGraphInspection>\n): ReadonlyArray<WorkspaceItemPresentation> => {\n const items = new Map<EntityId, {\n readonly entry: ReleaseDeliveryGraphInspection[\"entityProjections\"][number]\n readonly releaseIds: Set<ReleaseId>\n }>()\n const canonicalInspections = [...inspections].sort((left, right) => left.releaseId.localeCompare(right.releaseId))\n for (const inspection of canonicalInspections) {\n for (const entry of inspection.entityProjections) {\n const projection = entry.projection\n if (projection.entityState !== \"present\") continue\n const existing = items.get(projection.entityId)\n if (existing !== undefined) {\n existing.releaseIds.add(inspection.releaseId)\n continue\n }\n items.set(projection.entityId, { entry, releaseIds: new Set([inspection.releaseId]) })\n }\n }\n return [...items.values()].map(({ entry, releaseIds: membershipSet }) => {\n const releaseIds = [...membershipSet].sort((left, right) => left.localeCompare(right))\n return presentProjection(workspaceId, {\n ...entry,\n canonicalReleaseId: releaseIds[0] ?? null,\n releaseIds,\n releaseMembershipsTruncated: false\n })\n }).sort((left, right) => left.service.localeCompare(right.service) || left.key.localeCompare(right.key))\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{A as e,D as t,Ft as n,P as r,Pt as i,j as a,k as o,m as s,w as c,x as l}from"./client-OmvShYdC.js";import{t as u,u as d}from"./releaseRoutes-DSWkTh-E.js";import{t as f}from"./workspaceEntityPaths-xAl2jRFm.js";var p=a({hash:e,pathname:e,search:e,state:o(u)}),m=a({entityOrigin:a({_tag:t(`entity-origin/v2`),entityId:s,origin:p,workspaceId:c})}),h=e=>{if(e.includes(`?`)||e.includes(`#`))return null;let t=e.split(`/`);if(t.length!==5||t[0]!==``||t[1]!==`w`||t[3]!==`items`)return null;let i=r(c)(t[2]),a=r(s)(t[4]);return n(i)&&n(a)?{entityId:a.value,workspaceId:i.value}:null},g=e=>{let t=r(s)(e);return n(t)?t.value:null},_=e=>({hash:``,pathname:f(e),search:``,state:null}),v=e=>e.length<=2048&&(e.length===0||e.startsWith(`?`)),y=e=>e.length<=1024&&(e.length===0||e.startsWith(`#`)),b=(e,t)=>{if(e.length!==5&&e.length!==6||e[0]!==``||e[1]!==`w`||e[2]!==t||e[3]!==`releases`)return null;let n=r(l)(e[4]);return i(n)||e.length===6&&e[5]!==`preview`?null:{releaseId:n.value,workspaceId:t}},x=(e,t)=>{if(e.length>2048)return!1;let n=e.split(`/`);return n[0]!==``||n[1]!==`w`||n[2]!==t?!1:n.length===4?[`overview`,`work`,`items`,`timeline`].includes(n[3]??``):b(n,t)!==null},S=({hash:e,pathname:t,search:i,state:a})=>{let o=r(c)(t.split(`/`)[2]),s=n(o)?b(t.split(`/`),o.value):null;return{hash:e,pathname:t,search:i,state:s===null?null:d(a,s.workspaceId,s.releaseId)}},C=(e,t)=>{if(!x(e.pathname,t)||!v(e.search)||!y(e.hash))return!1;if(e.state===null)return!0;let n=b(e.pathname.split(`/`),t);return n!==null&&d(e.state,t,n.releaseId)!==null},w=(e,t)=>{let n=r(m)(e);if(i(n))return null;let a=n.value.entityOrigin;return a.workspaceId===t&&C(a.origin,t)?a.origin:null},T=(e,t,n,r)=>({entityOrigin:{_tag:`entity-origin/v2`,entityId:n,origin:w(e,t)??(C(r,t)?r:_(t)),workspaceId:t}}),E=(e,t,n)=>{let a=_(t),o=r(m)(e);if(i(o))return{isStored:!1,origin:a};let s=o.value.entityOrigin;return s.workspaceId===t&&s.entityId===n&&C(s.origin,t)?{isStored:!0,origin:s.origin}:{isStored:!1,origin:a}},D=({hash:e,pathname:t,search:n})=>`${t}${n}${e}`;export{D as a,E as i,S as n,h as o,T as r,g as t};
|
|
2
|
-
//# sourceMappingURL=workspaceEntityRoutes-CRcfSq7c.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workspaceEntityRoutes-CRcfSq7c.js","names":[],"sources":["../../../src/client/items/workspaceEntityRoutes.ts"],"sourcesContent":["import * as Option from \"effect/Option\"\nimport * as Schema from \"effect/Schema\"\n\nimport {\n EntityId,\n type EntityId as EntityIdType,\n ReleaseId,\n type ReleaseId as ReleaseIdType,\n WorkspaceId,\n type WorkspaceId as WorkspaceIdType\n} from \"../../domain/identifiers.js\"\nimport { type ReleaseRouteState, ReleaseRouteStateSchema, retainReleaseRouteState } from \"../releases/releaseRoutes.js\"\nimport { workspaceEntityParentPath } from \"../workspaceEntityPaths.js\"\n\nexport { workspaceEntityParentPath, workspaceEntityPath } from \"../workspaceEntityPaths.js\"\n\n/** Exact in-application location preserved while a canonical entity route is open. */\nexport interface WorkspaceEntityOrigin {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n readonly state: ReleaseRouteState | null\n}\n\n/** Versioned, bounded router state for one canonical entity activation. */\nexport interface WorkspaceEntityRouteState {\n readonly entityOrigin: {\n readonly _tag: \"entity-origin/v2\"\n readonly entityId: EntityIdType\n readonly origin: WorkspaceEntityOrigin\n readonly workspaceId: WorkspaceIdType\n }\n}\n\n/** Decoded entity origin plus whether it came from trusted matching history state. */\nexport interface ResolvedWorkspaceEntityOrigin {\n readonly isStored: boolean\n readonly origin: WorkspaceEntityOrigin\n}\n\n/** Decoded target of one exact canonical workspace entity href. */\nexport interface WorkspaceEntityTarget {\n readonly entityId: EntityIdType\n readonly workspaceId: WorkspaceIdType\n}\n\ninterface LocationParts {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n readonly state?: unknown\n}\n\nconst WorkspaceEntityOriginSchema = Schema.Struct({\n hash: Schema.String,\n pathname: Schema.String,\n search: Schema.String,\n state: Schema.NullOr(ReleaseRouteStateSchema)\n})\n\nconst WorkspaceEntityRouteStateSchema = Schema.Struct({\n entityOrigin: Schema.Struct({\n _tag: Schema.Literal(\"entity-origin/v2\"),\n entityId: EntityId,\n origin: WorkspaceEntityOriginSchema,\n workspaceId: WorkspaceId\n })\n})\n\n/** Decode only an exact canonical entity path, rejecting query, hash, and extra path material. */\nexport const workspaceEntityTargetFromHref = (href: string): WorkspaceEntityTarget | null => {\n if (href.includes(\"?\") || href.includes(\"#\")) return null\n const parts = href.split(\"/\")\n if (parts.length !== 5 || parts[0] !== \"\" || parts[1] !== \"w\" || parts[3] !== \"items\") return null\n const workspaceId = Schema.decodeUnknownOption(WorkspaceId)(parts[2])\n const entityId = Schema.decodeUnknownOption(EntityId)(parts[4])\n return Option.isSome(workspaceId) && Option.isSome(entityId)\n ? { entityId: entityId.value, workspaceId: workspaceId.value }\n : null\n}\n\n/** Decode one entity route segment at the browser boundary. */\nexport const decodeEntityRouteId = (value: unknown): EntityIdType | null => {\n const decoded = Schema.decodeUnknownOption(EntityId)(value)\n return Option.isSome(decoded) ? decoded.value : null\n}\n\nconst fallbackOrigin = (workspaceId: WorkspaceIdType): WorkspaceEntityOrigin => ({\n hash: \"\",\n pathname: workspaceEntityParentPath(workspaceId),\n search: \"\",\n state: null\n})\n\nconst isSearch = (search: string): boolean => search.length <= 2_048 && (search.length === 0 || search.startsWith(\"?\"))\n\nconst isHash = (hash: string): boolean => hash.length <= 1_024 && (hash.length === 0 || hash.startsWith(\"#\"))\n\nconst releaseOriginTarget = (\n parts: ReadonlyArray<string>,\n workspaceId: WorkspaceIdType\n): { readonly releaseId: ReleaseIdType; readonly workspaceId: WorkspaceIdType } | null => {\n if (parts.length !== 5 && parts.length !== 6) return null\n if (parts[0] !== \"\" || parts[1] !== \"w\" || parts[2] !== workspaceId || parts[3] !== \"releases\") return null\n const releaseId = Schema.decodeUnknownOption(ReleaseId)(parts[4])\n if (Option.isNone(releaseId) || (parts.length === 6 && parts[5] !== \"preview\")) return null\n return { releaseId: releaseId.value, workspaceId }\n}\n\nconst isRecognizedOriginPath = (pathname: string, workspaceId: WorkspaceIdType): boolean => {\n if (pathname.length > 2_048) return false\n const parts = pathname.split(\"/\")\n if (parts[0] !== \"\" || parts[1] !== \"w\" || parts[2] !== workspaceId) return false\n if (parts.length === 4) return [\"overview\", \"work\", \"items\", \"timeline\"].includes(parts[3] ?? \"\")\n return releaseOriginTarget(parts, workspaceId) !== null\n}\n\n/** Capture an exact location while retaining only matching, bounded release origin state. */\nexport const entityOriginFromLocation = ({\n hash,\n pathname,\n search,\n state\n}: LocationParts): WorkspaceEntityOrigin => {\n const workspaceId = Schema.decodeUnknownOption(WorkspaceId)(pathname.split(\"/\")[2])\n const target = Option.isSome(workspaceId) ? releaseOriginTarget(pathname.split(\"/\"), workspaceId.value) : null\n return {\n hash,\n pathname,\n search,\n state: target === null ? null : retainReleaseRouteState(state, target.workspaceId, target.releaseId)\n }\n}\n\n/** Confirm an origin is bounded and belongs to a supported page in the exact workspace. */\nexport const isSafeWorkspaceEntityOrigin = (\n origin: WorkspaceEntityOrigin,\n workspaceId: WorkspaceIdType\n): boolean => {\n if (!isRecognizedOriginPath(origin.pathname, workspaceId) || !isSearch(origin.search) || !isHash(origin.hash)) {\n return false\n }\n if (origin.state === null) return true\n const target = releaseOriginTarget(origin.pathname.split(\"/\"), workspaceId)\n return target !== null && retainReleaseRouteState(origin.state, workspaceId, target.releaseId) !== null\n}\n\nconst reusableStoredOrigin = (\n state: unknown,\n workspaceId: WorkspaceIdType\n): WorkspaceEntityOrigin | null => {\n const decoded = Schema.decodeUnknownOption(WorkspaceEntityRouteStateSchema)(state)\n if (Option.isNone(decoded)) return null\n const marker = decoded.value.entityOrigin\n return marker.workspaceId === workspaceId && isSafeWorkspaceEntityOrigin(marker.origin, workspaceId)\n ? marker.origin\n : null\n}\n\n/**\n * Construct bounded entity route state.\n *\n * A previously validated entity origin is carried through related-entity navigation so the\n * shell's explicit Back action still returns to the root activation surface.\n */\nexport const makeWorkspaceEntityRouteState = (\n state: unknown,\n workspaceId: WorkspaceIdType,\n entityId: EntityIdType,\n origin: WorkspaceEntityOrigin\n): WorkspaceEntityRouteState => ({\n entityOrigin: {\n _tag: \"entity-origin/v2\",\n entityId,\n origin: reusableStoredOrigin(state, workspaceId) ??\n (isSafeWorkspaceEntityOrigin(origin, workspaceId) ? origin : fallbackOrigin(workspaceId)),\n workspaceId\n }\n})\n\n/** Decode safe history state for the exact workspace/entity pair or use the Items parent. */\nexport const resolveWorkspaceEntityOrigin = (\n state: unknown,\n workspaceId: WorkspaceIdType,\n entityId: EntityIdType\n): ResolvedWorkspaceEntityOrigin => {\n const fallback = fallbackOrigin(workspaceId)\n const decoded = Schema.decodeUnknownOption(WorkspaceEntityRouteStateSchema)(state)\n if (Option.isNone(decoded)) return { isStored: false, origin: fallback }\n const marker = decoded.value.entityOrigin\n return marker.workspaceId === workspaceId &&\n marker.entityId === entityId &&\n isSafeWorkspaceEntityOrigin(marker.origin, workspaceId)\n ? { isStored: true, origin: marker.origin }\n : { isStored: false, origin: fallback }\n}\n\n/** Serialize an exact validated origin for React Router navigation. */\nexport const workspaceEntityOriginHref = ({\n hash,\n pathname,\n search\n}: WorkspaceEntityOrigin): string => `${pathname}${search}${hash}`\n"],"mappings":"wNAqDA,IAAM,EAA8B,EAAc,CAChD,KAAM,EACN,SAAU,EACV,OAAQ,EACR,MAAO,EAAc,CAAuB,CAC9C,CAAC,EAEK,EAAkC,EAAc,CACpD,aAAc,EAAc,CAC1B,KAAM,EAAe,kBAAkB,EACvC,SAAU,EACV,OAAQ,EACR,YAAa,CACf,CAAC,CACH,CAAC,EAGY,EAAiC,GAA+C,CAC3F,GAAI,EAAK,SAAS,GAAG,GAAK,EAAK,SAAS,GAAG,EAAG,OAAO,KACrD,IAAM,EAAQ,EAAK,MAAM,GAAG,EAC5B,GAAI,EAAM,SAAW,GAAK,EAAM,KAAO,IAAM,EAAM,KAAO,KAAO,EAAM,KAAO,QAAS,OAAO,KAC9F,IAAM,EAAc,EAA2B,CAAW,CAAC,CAAC,EAAM,EAAE,EAC9D,EAAW,EAA2B,CAAQ,CAAC,CAAC,EAAM,EAAE,EAC9D,OAAO,EAAc,CAAW,GAAK,EAAc,CAAQ,EACvD,CAAE,SAAU,EAAS,MAAO,YAAa,EAAY,KAAM,EAC3D,IACN,EAGa,EAAuB,GAAwC,CAC1E,IAAM,EAAU,EAA2B,CAAQ,CAAC,CAAC,CAAK,EAC1D,OAAO,EAAc,CAAO,EAAI,EAAQ,MAAQ,IAClD,EAEM,EAAkB,IAAyD,CAC/E,KAAM,GACN,SAAU,EAA0B,CAAW,EAC/C,OAAQ,GACR,MAAO,IACT,GAEM,EAAY,GAA4B,EAAO,QAAU,OAAU,EAAO,SAAW,GAAK,EAAO,WAAW,GAAG,GAE/G,EAAU,GAA0B,EAAK,QAAU,OAAU,EAAK,SAAW,GAAK,EAAK,WAAW,GAAG,GAErG,GACJ,EACA,IACwF,CAExF,GADI,EAAM,SAAW,GAAK,EAAM,SAAW,GACvC,EAAM,KAAO,IAAM,EAAM,KAAO,KAAO,EAAM,KAAO,GAAe,EAAM,KAAO,WAAY,OAAO,KACvG,IAAM,EAAY,EAA2B,CAAS,CAAC,CAAC,EAAM,EAAE,EAEhE,OADI,EAAc,CAAS,GAAM,EAAM,SAAW,GAAK,EAAM,KAAO,UAAmB,KAChF,CAAE,UAAW,EAAU,MAAO,aAAY,CACnD,EAEM,GAA0B,EAAkB,IAA0C,CAC1F,GAAI,EAAS,OAAS,KAAO,MAAO,GACpC,IAAM,EAAQ,EAAS,MAAM,GAAG,EAGhC,OAFI,EAAM,KAAO,IAAM,EAAM,KAAO,KAAO,EAAM,KAAO,EAAoB,GACxE,EAAM,SAAW,EAAU,CAAC,WAAY,OAAQ,QAAS,UAAU,CAAC,CAAC,SAAS,EAAM,IAAM,EAAE,EACzF,EAAoB,EAAO,CAAW,IAAM,IACrD,EAGa,GAA4B,CACvC,OACA,WACA,SACA,WAC0C,CAC1C,IAAM,EAAc,EAA2B,CAAW,CAAC,CAAC,EAAS,MAAM,GAAG,CAAC,CAAC,EAAE,EAC5E,EAAS,EAAc,CAAW,EAAI,EAAoB,EAAS,MAAM,GAAG,EAAG,EAAY,KAAK,EAAI,KAC1G,MAAO,CACL,OACA,WACA,SACA,MAAO,IAAW,KAAO,KAAO,EAAwB,EAAO,EAAO,YAAa,EAAO,SAAS,CACrG,CACF,EAGa,GACX,EACA,IACY,CACZ,GAAI,CAAC,EAAuB,EAAO,SAAU,CAAW,GAAK,CAAC,EAAS,EAAO,MAAM,GAAK,CAAC,EAAO,EAAO,IAAI,EAC1G,MAAO,GAET,GAAI,EAAO,QAAU,KAAM,MAAO,GAClC,IAAM,EAAS,EAAoB,EAAO,SAAS,MAAM,GAAG,EAAG,CAAW,EAC1E,OAAO,IAAW,MAAQ,EAAwB,EAAO,MAAO,EAAa,EAAO,SAAS,IAAM,IACrG,EAEM,GACJ,EACA,IACiC,CACjC,IAAM,EAAU,EAA2B,CAA+B,CAAC,CAAC,CAAK,EACjF,GAAI,EAAc,CAAO,EAAG,OAAO,KACnC,IAAM,EAAS,EAAQ,MAAM,aAC7B,OAAO,EAAO,cAAgB,GAAe,EAA4B,EAAO,OAAQ,CAAW,EAC/F,EAAO,OACP,IACN,EAQa,GACX,EACA,EACA,EACA,KAC+B,CAC/B,aAAc,CACZ,KAAM,mBACN,WACA,OAAQ,EAAqB,EAAO,CAAW,IAC5C,EAA4B,EAAQ,CAAW,EAAI,EAAS,EAAe,CAAW,GACzF,aACF,CACF,GAGa,GACX,EACA,EACA,IACkC,CAClC,IAAM,EAAW,EAAe,CAAW,EACrC,EAAU,EAA2B,CAA+B,CAAC,CAAC,CAAK,EACjF,GAAI,EAAc,CAAO,EAAG,MAAO,CAAE,SAAU,GAAO,OAAQ,CAAS,EACvE,IAAM,EAAS,EAAQ,MAAM,aAC7B,OAAO,EAAO,cAAgB,GAC1B,EAAO,WAAa,GACpB,EAA4B,EAAO,OAAQ,CAAW,EACtD,CAAE,SAAU,GAAM,OAAQ,EAAO,MAAO,EACxC,CAAE,SAAU,GAAO,OAAQ,CAAS,CAC1C,EAGa,GAA6B,CACxC,OACA,WACA,YACmC,GAAG,IAAW,IAAS"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"manualPluginSynchronization-C0aHB4UM.js","names":[],"sources":["../../../src/server/application/pluginSynchronizationAuthority.ts","../../../src/server/application/relationshipInference.ts","../../../src/server/application/relationshipInferenceMaterialization.ts","../../../src/server/application/normalizedPluginPageMaterialization.ts","../../../src/server/application/manualPluginSynchronization.ts"],"sourcesContent":["import * as Effect from \"effect/Effect\"\nimport * as Option from \"effect/Option\"\n\nimport type { PluginConnectionId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport type { ProviderId } from \"../../domain/sourceRevision.js\"\nimport type { PersistenceOperationFailure, PersistenceService } from \"../persistence/Persistence.js\"\nimport type { PluginConnectionRecord } from \"../persistence/repositories/models.js\"\nimport { PluginConflictFailure } from \"../plugins/failures.js\"\n\n/** Exact mutable host state that authorized one manual synchronization runtime. */\nexport interface PluginSynchronizationAuthority {\n readonly workspaceId: WorkspaceId\n readonly pluginConnectionId: PluginConnectionId\n readonly providerId: ProviderId\n readonly connectionRevision: number\n readonly configurationRevision: number | null\n}\n\nconst conflict = () =>\n new PluginConflictFailure({\n operation: \"manual-sync\",\n diagnosticCode: \"manual-sync-runtime-authority-changed\"\n })\n\nconst authorityFor = Effect.fn(\"PluginSynchronizationAuthority.forConnection\")(function*(\n persistence: PersistenceService,\n connection: PluginConnectionRecord\n) {\n const configuration = yield* persistence.pluginConfigurations.get(\n connection.workspaceId,\n connection.pluginConnectionId\n )\n return {\n workspaceId: connection.workspaceId,\n pluginConnectionId: connection.pluginConnectionId,\n providerId: connection.providerId,\n connectionRevision: connection.revision,\n configurationRevision: Option.isSome(configuration) ? configuration.value.revision : null\n } satisfies PluginSynchronizationAuthority\n})\n\n/** Capture connection and configuration revisions in one durable read transaction. */\nexport const capturePluginSynchronizationAuthority = Effect.fn(\n \"PluginSynchronizationAuthority.capture\"\n)(function*(\n persistence: PersistenceService,\n workspaceId: WorkspaceId,\n pluginConnectionId: PluginConnectionId\n): Effect.fn.Return<\n { readonly connection: PluginConnectionRecord; readonly authority: PluginSynchronizationAuthority },\n PersistenceOperationFailure\n> {\n return yield* persistence.transact(Effect.gen(function*() {\n const connection = yield* persistence.pluginConnections.get(workspaceId, pluginConnectionId)\n const authority = yield* authorityFor(persistence, connection)\n return { connection, authority }\n }))\n})\n\n/** Reject a write transaction when its runtime no longer owns current connection authority. */\nexport const verifyPluginSynchronizationAuthority = Effect.fn(\n \"PluginSynchronizationAuthority.verify\"\n)(function*(\n persistence: PersistenceService,\n expected: PluginSynchronizationAuthority\n): Effect.fn.Return<void, PluginConflictFailure | PersistenceOperationFailure> {\n const connection = yield* persistence.pluginConnections.get(\n expected.workspaceId,\n expected.pluginConnectionId\n ).pipe(\n Effect.catchTag(\"RecordNotFoundError\", () => conflict())\n )\n const current = yield* authorityFor(persistence, connection)\n if (\n !connection.isEnabled ||\n current.providerId !== expected.providerId ||\n current.connectionRevision !== expected.connectionRevision ||\n current.configurationRevision !== expected.configurationRevision\n ) {\n return yield* conflict()\n }\n})\n","import type {\n DeliveryEntityKind,\n DeliveryEntityProjection,\n DeliveryRelationship,\n RelationshipEndpointKind,\n RelationshipKind\n} from \"../../domain/deliveryGraph.js\"\nimport type { EntityId, GraphNodeId, ReleaseId } from \"../../domain/identifiers.js\"\n\n/** One current canonical entity exposed to provider-neutral relationship rules. */\nexport interface RelationshipInferenceEntity {\n readonly nodeId: GraphNodeId\n readonly projection: DeliveryEntityProjection\n readonly releaseIds: ReadonlyArray<ReleaseId>\n}\n\n/** One canonical release exposed without provider-specific version objects. */\nexport interface RelationshipInferenceRelease {\n readonly nodeId: GraphNodeId\n readonly releaseId: ReleaseId\n readonly version: string\n}\n\nexport type RelationshipInferenceEndpoint =\n | Readonly<{ readonly _tag: \"resolved\"; readonly kind: RelationshipEndpointKind; readonly nodeId: GraphNodeId }>\n | Readonly<{\n readonly _tag: \"missing\"\n readonly identityKey: string\n readonly kind: DeliveryEntityKind\n readonly missingKey: string\n }>\n\n/** Explainable candidate ready for evidence and ledger materialization. */\nexport interface RelationshipInferenceCandidate {\n readonly confidence: Readonly<{ readonly score: number; readonly rationale: string }> | null\n readonly evidenceEntityId: EntityId | null\n readonly identityKey: string\n readonly kind: RelationshipKind\n readonly lifecycle: \"inferred\" | \"missing\"\n readonly observationKey: string\n readonly releaseId: ReleaseId\n readonly ruleId: string\n readonly source: RelationshipInferenceEndpoint\n readonly target: RelationshipInferenceEndpoint\n}\n\nexport interface RelationshipInferenceResult {\n readonly candidates: ReadonlyArray<RelationshipInferenceCandidate>\n readonly obsoleteGapIdentityKeys: ReadonlyArray<string>\n readonly obsoleteRelationshipIds: ReadonlyArray<DeliveryRelationship[\"relationshipId\"]>\n readonly truncated: boolean\n}\n\nconst MAXIMUM_INFERENCE_CANDIDATES = 2_000\n\ninterface CandidateAccumulator {\n readonly candidates: Array<RelationshipInferenceCandidate>\n truncated: boolean\n}\n\nconst addCandidate = (\n accumulator: CandidateAccumulator,\n candidate: RelationshipInferenceCandidate\n): void => {\n if (accumulator.candidates.length >= MAXIMUM_INFERENCE_CANDIDATES) {\n accumulator.truncated = true\n return\n }\n accumulator.candidates.push(candidate)\n}\n\nconst OWNED_RULE_IDS = new Set([\n \"codepipeline-trigger-revision-v1\",\n \"confluence-jira-link-v1\",\n \"confluence-release-link-v1\",\n \"jira-key-in-clockify-description-v1\",\n \"jira-key-in-confluence-metadata-v1\",\n \"jira-key-in-pull-request-metadata-v1\",\n \"release-in-confluence-metadata-v1\"\n])\n\nconst present = (entity: RelationshipInferenceEntity): boolean => entity.projection.entityState === \"present\"\n\nconst resolved = (kind: RelationshipEndpointKind, nodeId: GraphNodeId): RelationshipInferenceEndpoint => ({\n _tag: \"resolved\",\n kind,\n nodeId\n})\n\nconst missing = (\n kind: DeliveryEntityKind,\n missingKey: string,\n identityKey: string\n): RelationshipInferenceEndpoint => ({\n _tag: \"missing\",\n identityKey,\n kind,\n missingKey\n})\n\nconst currentRelationship = (relationship: DeliveryRelationship): boolean =>\n relationship.lifecycle._tag !== \"missing\" &&\n relationship.lifecycle._tag !== \"rejected\" &&\n relationship.lifecycle._tag !== \"superseded\"\n\nconst currentExternalRelationship = (relationship: DeliveryRelationship): boolean =>\n currentRelationship(relationship) &&\n !(\n relationship.lifecycle._tag === \"inferred\" &&\n relationship.provenance._tag === \"rule\" &&\n OWNED_RULE_IDS.has(relationship.provenance.ruleId)\n )\n\nconst currentOwnedRelationship = (relationship: DeliveryRelationship): boolean =>\n currentRelationship(relationship) &&\n relationship.lifecycle._tag === \"inferred\" &&\n relationship.provenance._tag === \"rule\" &&\n OWNED_RULE_IDS.has(relationship.provenance.ruleId)\n\nconst currentInferenceRelationship = (relationship: DeliveryRelationship): boolean =>\n relationship.lifecycle._tag !== \"rejected\" &&\n relationship.lifecycle._tag !== \"superseded\" &&\n relationship.provenance._tag === \"rule\" &&\n (relationship.provenance.ruleId === \"delivery-gap-v1\" || OWNED_RULE_IDS.has(relationship.provenance.ruleId))\n\nconst relationshipInRelease = (relationship: DeliveryRelationship, releaseId: ReleaseId): boolean =>\n relationship.scope?._tag === \"release\" && relationship.scope.releaseId === releaseId\n\nconst containsToken = (text: string, token: string): boolean => {\n const normalizedText = text.toUpperCase()\n const normalizedToken = token.toUpperCase()\n let offset = normalizedText.indexOf(normalizedToken)\n while (offset >= 0) {\n const before = normalizedText[offset - 1]\n const after = normalizedText[offset + normalizedToken.length]\n const boundary = (character: string | undefined) => character === undefined || !/[A-Z0-9]/u.test(character)\n if (boundary(before) && boundary(after)) return true\n offset = normalizedText.indexOf(normalizedToken, offset + normalizedToken.length)\n }\n return false\n}\n\nconst containsReleaseVersion = (text: string, version: string): boolean => {\n const normalizedText = text.toUpperCase()\n const normalizedVersion = version.toUpperCase()\n let offset = normalizedText.indexOf(normalizedVersion)\n while (offset >= 0) {\n const before = normalizedText[offset - 1]\n const after = normalizedText[offset + normalizedVersion.length]\n const boundary = (character: string | undefined) => character === undefined || !/[A-Z0-9._+-]/u.test(character)\n if (boundary(before) && boundary(after)) return true\n offset = normalizedText.indexOf(normalizedVersion, offset + normalizedVersion.length)\n }\n return false\n}\n\nconst metadata = (entity: RelationshipInferenceEntity): string => {\n const details = entity.projection.details\n return details._tag === \"pull-request\"\n ? [entity.projection.title, entity.projection.displayKey, details.sourceBranch, details.targetBranch].join(\"\\n\")\n : [entity.projection.title, entity.projection.displayKey].join(\"\\n\")\n}\n\nconst observationKey = (...entities: ReadonlyArray<RelationshipInferenceEntity>): string =>\n entities\n .map(({ projection }) => `${projection.entityId}@${String(projection.projectionRevision)}`)\n .sort()\n .join(\"+\")\n\nconst inferred = (input: Omit<RelationshipInferenceCandidate, \"lifecycle\">): RelationshipInferenceCandidate => ({\n ...input,\n lifecycle: \"inferred\"\n})\n\nconst gap = (input: {\n readonly identityKey: string\n readonly kind: RelationshipKind\n readonly releaseId: ReleaseId\n readonly source: RelationshipInferenceEndpoint\n readonly target: RelationshipInferenceEndpoint\n}): RelationshipInferenceCandidate => ({\n ...input,\n confidence: null,\n evidenceEntityId: null,\n lifecycle: \"missing\",\n observationKey: input.identityKey,\n ruleId: \"delivery-gap-v1\"\n})\n\nconst candidateIdentity = (\n kind: RelationshipKind,\n releaseId: ReleaseId,\n source: GraphNodeId,\n target: GraphNodeId\n): string => `relationship:${kind}:${releaseId}:${source}:${target}`\n\nconst issueGapIdentity = (releaseId: ReleaseId, issueNodeId: GraphNodeId): string =>\n `gap:implements:${releaseId}:${issueNodeId}`\n\nconst pipelineGapIdentity = (releaseId: ReleaseId, pullRequestNodeId: GraphNodeId): string =>\n `gap:delivered-by:${releaseId}:${pullRequestNodeId}`\n\nconst candidateGapKey = (candidate: RelationshipInferenceCandidate): string | null => {\n if (candidate.lifecycle !== \"missing\") return null\n if (candidate.kind === \"implements\" && candidate.target._tag === \"resolved\") {\n return `${candidate.kind}:${candidate.releaseId}:${candidate.target.nodeId}`\n }\n if (candidate.kind === \"delivered-by\" && candidate.source._tag === \"resolved\") {\n return `${candidate.kind}:${candidate.releaseId}:${candidate.source.nodeId}`\n }\n return null\n}\n\nconst relationshipGapKey = (relationship: DeliveryRelationship): string | null => {\n if (\n relationship.lifecycle._tag !== \"missing\" ||\n relationship.provenance._tag !== \"rule\" ||\n relationship.provenance.ruleId !== \"delivery-gap-v1\" ||\n relationship.scope?._tag !== \"release\"\n ) return null\n if (relationship.kind === \"implements\") {\n return `${relationship.kind}:${relationship.scope.releaseId}:${relationship.targetNodeId}`\n }\n if (relationship.kind === \"delivered-by\") {\n return `${relationship.kind}:${relationship.scope.releaseId}:${relationship.sourceNodeId}`\n }\n return null\n}\n\nconst hasRelationship = (\n relationships: ReadonlyArray<DeliveryRelationship>,\n releaseId: ReleaseId,\n kind: RelationshipKind,\n sourceNodeId: GraphNodeId | null,\n targetNodeId: GraphNodeId | null\n): boolean =>\n relationships.some(\n (relationship) =>\n currentExternalRelationship(relationship) &&\n relationshipInRelease(relationship, releaseId) &&\n relationship.kind === kind &&\n (sourceNodeId === null || relationship.sourceNodeId === sourceNodeId) &&\n (targetNodeId === null || relationship.targetNodeId === targetNodeId)\n )\n\nconst addIssueAndTimeCandidates = (\n entities: ReadonlyArray<RelationshipInferenceEntity>,\n accumulator: CandidateAccumulator\n) => {\n const issues = entities.filter((entity) => entity.projection.details._tag === \"issue\")\n const timeEntries = entities.filter((entity) => entity.projection.details._tag === \"time-entry\")\n for (const timeEntry of timeEntries) {\n for (const issue of issues) {\n const details = issue.projection.details\n if (details._tag !== \"issue\" || !containsToken(metadata(timeEntry), details.key)) continue\n for (const releaseId of issue.releaseIds) {\n addCandidate(\n accumulator,\n inferred({\n confidence: { score: 0.95, rationale: `The Clockify description contains Jira key ${details.key}.` },\n evidenceEntityId: timeEntry.projection.entityId,\n identityKey: candidateIdentity(\"tracks-time-for\", releaseId, timeEntry.nodeId, issue.nodeId),\n kind: \"tracks-time-for\",\n observationKey: observationKey(timeEntry, issue),\n releaseId,\n ruleId: \"jira-key-in-clockify-description-v1\",\n source: resolved(\"time-entry\", timeEntry.nodeId),\n target: resolved(\"issue\", issue.nodeId)\n })\n )\n }\n }\n }\n}\n\nconst addDocumentationCandidates = (\n entities: ReadonlyArray<RelationshipInferenceEntity>,\n releases: ReadonlyArray<RelationshipInferenceRelease>,\n accumulator: CandidateAccumulator\n) => {\n const issues = entities.filter((entity) => entity.projection.details._tag === \"issue\")\n const releaseVersionCounts = new Map<string, number>()\n for (const release of releases) {\n const version = release.version.toUpperCase()\n releaseVersionCounts.set(version, (releaseVersionCounts.get(version) ?? 0) + 1)\n }\n const pages = entities.filter(\n (entity) => entity.projection.details._tag === \"page\" && entity.projection.details.status === \"current\"\n )\n for (const page of pages) {\n const pageDetails = page.projection.details\n if (pageDetails._tag !== \"page\") continue\n const pageMetadata = metadata(page)\n for (const issue of issues) {\n const details = issue.projection.details\n if (details._tag !== \"issue\") continue\n const explicitLink = pageDetails.linkedIssueKeys?.some((key) =>\n key.toUpperCase() === details.key.toUpperCase()\n ) ?? false\n if (!explicitLink && !containsToken(pageMetadata, details.key)) continue\n for (const releaseId of issue.releaseIds) {\n addCandidate(\n accumulator,\n inferred({\n confidence: {\n score: explicitLink ? 0.97 : 0.9,\n rationale: explicitLink\n ? `Confluence metadata links Jira key ${details.key}.`\n : `Confluence page metadata contains Jira key ${details.key}.`\n },\n evidenceEntityId: page.projection.entityId,\n identityKey: candidateIdentity(\"documented-by\", releaseId, issue.nodeId, page.nodeId),\n kind: \"documented-by\",\n observationKey: observationKey(page, issue),\n releaseId,\n ruleId: explicitLink ? \"confluence-jira-link-v1\" : \"jira-key-in-confluence-metadata-v1\",\n source: resolved(\"issue\", issue.nodeId),\n target: resolved(\"page\", page.nodeId)\n })\n )\n }\n }\n for (const release of releases) {\n if ((releaseVersionCounts.get(release.version.toUpperCase()) ?? 0) > 1) continue\n const explicitLink = pageDetails.linkedReleaseVersions?.some(\n (version) => version.toUpperCase() === release.version.toUpperCase()\n ) ?? false\n if (!explicitLink && !containsReleaseVersion(pageMetadata, release.version)) continue\n addCandidate(\n accumulator,\n inferred({\n confidence: {\n score: explicitLink ? 0.96 : 0.88,\n rationale: explicitLink\n ? `Confluence metadata links release ${release.version}.`\n : `Confluence page metadata contains release ${release.version}.`\n },\n evidenceEntityId: page.projection.entityId,\n identityKey: candidateIdentity(\"documented-by\", release.releaseId, release.nodeId, page.nodeId),\n kind: \"documented-by\",\n observationKey: observationKey(page),\n releaseId: release.releaseId,\n ruleId: explicitLink ? \"confluence-release-link-v1\" : \"release-in-confluence-metadata-v1\",\n source: resolved(\"release\", release.nodeId),\n target: resolved(\"page\", page.nodeId)\n })\n )\n }\n }\n}\n\n/**\n * Infer a deterministic relationship set from current canonical facts. Rules\n * only propose `inferred` or `missing`; confirmation remains governed.\n */\nexport const deriveRelationshipInference = (input: {\n readonly entities: ReadonlyArray<RelationshipInferenceEntity>\n readonly rejectedCandidateIdentityKeys?: ReadonlySet<string>\n readonly releases: ReadonlyArray<RelationshipInferenceRelease>\n readonly relationships: ReadonlyArray<DeliveryRelationship>\n}): RelationshipInferenceResult => {\n const entities = input.entities.filter(present).map((entity) => ({\n ...entity,\n releaseIds: entity.releaseIds.filter((releaseId) => {\n const touchesEntity = (relationship: DeliveryRelationship) =>\n relationshipInRelease(relationship, releaseId) &&\n (relationship.sourceNodeId === entity.nodeId || relationship.targetNodeId === entity.nodeId)\n const inferenceMembership = input.relationships.some(\n (relationship) => currentInferenceRelationship(relationship) && touchesEntity(relationship)\n )\n return !inferenceMembership ||\n input.relationships.some((relationship) =>\n currentExternalRelationship(relationship) &&\n touchesEntity(relationship)\n )\n })\n }))\n const issues = entities.filter((entity) => entity.projection.details._tag === \"issue\")\n const pullRequests = entities.filter((entity) => entity.projection.details._tag === \"pull-request\")\n const pipelines = entities.filter((entity) => entity.projection.details._tag === \"pipeline-execution\")\n const accumulator: CandidateAccumulator = { candidates: [], truncated: false }\n const obsoleteGaps = new Set<string>()\n const inferredIssueLinks = new Set<string>()\n const pullRequestReleases = new Map<GraphNodeId, Set<ReleaseId>>()\n\n for (const pullRequest of pullRequests) {\n const details = pullRequest.projection.details\n if (details._tag !== \"pull-request\") continue\n const releaseIds = new Set(\n pullRequest.releaseIds.filter((releaseId) => {\n const touchesPullRequest = (relationship: DeliveryRelationship) =>\n relationshipInRelease(relationship, releaseId) &&\n (relationship.sourceNodeId === pullRequest.nodeId || relationship.targetNodeId === pullRequest.nodeId)\n const ownedMembership = input.relationships.some(\n (relationship) => currentOwnedRelationship(relationship) && touchesPullRequest(relationship)\n )\n return !ownedMembership || input.relationships.some(\n (relationship) => currentExternalRelationship(relationship) && touchesPullRequest(relationship)\n )\n })\n )\n for (const issue of issues) {\n const issueDetails = issue.projection.details\n if (issueDetails._tag !== \"issue\" || !containsToken(metadata(pullRequest), issueDetails.key)) continue\n for (const releaseId of issue.releaseIds) {\n const identityKey = candidateIdentity(\"implements\", releaseId, pullRequest.nodeId, issue.nodeId)\n if (!(input.rejectedCandidateIdentityKeys?.has(identityKey) ?? false)) {\n releaseIds.add(releaseId)\n inferredIssueLinks.add(`${releaseId}:${issue.nodeId}`)\n obsoleteGaps.add(issueGapIdentity(releaseId, issue.nodeId))\n }\n addCandidate(\n accumulator,\n inferred({\n confidence: {\n score: containsToken(pullRequest.projection.title, issueDetails.key) ? 0.98 : 0.94,\n rationale: `The immutable pull-request metadata contains Jira key ${issueDetails.key}.`\n },\n evidenceEntityId: pullRequest.projection.entityId,\n identityKey,\n kind: \"implements\",\n observationKey: observationKey(pullRequest, issue),\n releaseId,\n ruleId: \"jira-key-in-pull-request-metadata-v1\",\n source: resolved(\"pull-request\", pullRequest.nodeId),\n target: resolved(\"issue\", issue.nodeId)\n })\n )\n }\n }\n for (const relationship of input.relationships) {\n if (\n currentExternalRelationship(relationship) &&\n relationship.kind === \"implements\" &&\n relationship.sourceNodeId === pullRequest.nodeId &&\n relationship.scope?._tag === \"release\"\n ) {\n releaseIds.add(relationship.scope.releaseId)\n }\n }\n pullRequestReleases.set(pullRequest.nodeId, releaseIds)\n }\n\n for (const issue of issues) {\n for (const releaseId of issue.releaseIds) {\n const identityKey = issueGapIdentity(releaseId, issue.nodeId)\n if (\n inferredIssueLinks.has(`${releaseId}:${issue.nodeId}`) ||\n hasRelationship(input.relationships, releaseId, \"implements\", null, issue.nodeId)\n ) {\n obsoleteGaps.add(identityKey)\n } else {\n const details = issue.projection.details\n if (details._tag !== \"issue\") continue\n addCandidate(\n accumulator,\n gap({\n identityKey,\n kind: \"implements\",\n releaseId,\n source: missing(\"pull-request\", `${details.key}:pull-request`, issue.nodeId),\n target: resolved(\"issue\", issue.nodeId)\n })\n )\n }\n }\n }\n\n const inferredPipelineLinks = new Set<string>()\n for (const pullRequest of pullRequests) {\n const pullRequestDetails = pullRequest.projection.details\n if (pullRequestDetails._tag !== \"pull-request\") continue\n for (const pipeline of pipelines) {\n const pipelineDetails = pipeline.projection.details\n if (\n pipelineDetails._tag !== \"pipeline-execution\" ||\n pipelineDetails.triggerRevision !== pullRequestDetails.headRevision\n ) {\n continue\n }\n for (const releaseId of pullRequestReleases.get(pullRequest.nodeId) ?? []) {\n const identityKey = candidateIdentity(\"delivered-by\", releaseId, pullRequest.nodeId, pipeline.nodeId)\n if (!(input.rejectedCandidateIdentityKeys?.has(identityKey) ?? false)) {\n inferredPipelineLinks.add(`${releaseId}:${pullRequest.nodeId}`)\n obsoleteGaps.add(pipelineGapIdentity(releaseId, pullRequest.nodeId))\n }\n addCandidate(\n accumulator,\n inferred({\n confidence: {\n score: 0.99,\n rationale:\n `The pipeline trigger revision exactly matches pull-request head ${pullRequestDetails.headRevision}.`\n },\n evidenceEntityId: pipeline.projection.entityId,\n identityKey,\n kind: \"delivered-by\",\n observationKey: observationKey(pullRequest, pipeline),\n releaseId,\n ruleId: \"codepipeline-trigger-revision-v1\",\n source: resolved(\"pull-request\", pullRequest.nodeId),\n target: resolved(\"pipeline-execution\", pipeline.nodeId)\n })\n )\n }\n }\n }\n\n for (const pullRequest of pullRequests) {\n for (const releaseId of pullRequestReleases.get(pullRequest.nodeId) ?? []) {\n const identityKey = pipelineGapIdentity(releaseId, pullRequest.nodeId)\n if (\n inferredPipelineLinks.has(`${releaseId}:${pullRequest.nodeId}`) ||\n hasRelationship(input.relationships, releaseId, \"delivered-by\", pullRequest.nodeId, null) ||\n hasRelationship(input.relationships, releaseId, \"verified-by\", pullRequest.nodeId, null)\n ) {\n obsoleteGaps.add(identityKey)\n } else {\n addCandidate(\n accumulator,\n gap({\n identityKey,\n kind: \"delivered-by\",\n releaseId,\n source: resolved(\"pull-request\", pullRequest.nodeId),\n target: missing(\n \"pipeline-execution\",\n `${pullRequest.projection.displayKey}:pipeline-execution`,\n pullRequest.nodeId\n )\n })\n )\n }\n }\n }\n\n addIssueAndTimeCandidates(entities, accumulator)\n addDocumentationCandidates(entities, input.releases, accumulator)\n const unique = new Map(accumulator.candidates.map((candidate) => [candidate.identityKey, candidate]))\n const candidateEdges = new Set(\n [...unique.values()].flatMap((candidate) =>\n candidate.lifecycle === \"inferred\" && candidate.source._tag === \"resolved\" && candidate.target._tag === \"resolved\"\n ? [`${candidate.kind}:${candidate.releaseId}:${candidate.source.nodeId}:${candidate.target.nodeId}`]\n : []\n )\n )\n const candidateGaps = new Set(\n [...unique.values()].flatMap((candidate) => {\n const key = candidateGapKey(candidate)\n return key === null ? [] : [key]\n })\n )\n const obsoleteRelationshipIds = input.relationships.flatMap((relationship) => {\n const gapKey = relationshipGapKey(relationship)\n const obsoleteInference = relationship.lifecycle._tag === \"inferred\" &&\n relationship.provenance._tag === \"rule\" &&\n OWNED_RULE_IDS.has(relationship.provenance.ruleId) &&\n relationship.scope?._tag === \"release\" &&\n !candidateEdges.has(\n `${relationship.kind}:${relationship.scope.releaseId}:${relationship.sourceNodeId}:${relationship.targetNodeId}`\n )\n const obsoleteGap = gapKey !== null && !candidateGaps.has(gapKey)\n return obsoleteInference || obsoleteGap ? [relationship.relationshipId] : []\n })\n return {\n candidates: [...unique.values()].sort((left, right) => left.identityKey.localeCompare(right.identityKey)),\n obsoleteGapIdentityKeys: [...obsoleteGaps].sort(),\n obsoleteRelationshipIds: [...new Set(obsoleteRelationshipIds)].sort(),\n truncated: accumulator.truncated\n }\n}\n","import * as DateTime from \"effect/DateTime\"\nimport * as Effect from \"effect/Effect\"\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\n\nimport {\n type DeliveryNode,\n type DeliveryRelationship,\n type EvidenceClaim,\n type EvidenceItem,\n LedgerRevision\n} from \"../../domain/deliveryGraph.js\"\nimport type { PluginHealth } from \"../../domain/freshness.js\"\nimport { EvidenceClaimId, EvidenceId, GraphNodeId, RelationshipId, type WorkspaceId } from \"../../domain/identifiers.js\"\nimport type { UtcTimestamp } from \"../../domain/utcTimestamp.js\"\nimport { PersistenceOperationError } from \"../persistence/errors.js\"\nimport type { PersistenceOperationFailure, PersistenceService } from \"../persistence/Persistence.js\"\nimport { DeliveryGraphWriteBatch } from \"../persistence/repositories/deliveryGraphRepository.js\"\nimport type { EntityRecord } from \"../persistence/repositories/models.js\"\nimport { PluginStreamKey } from \"../persistence/repositories/pluginRuntimeModels.js\"\nimport { firstPartySyncStreamKey } from \"../plugins/firstPartySynchronization.js\"\nimport {\n deriveRelationshipInference,\n type RelationshipInferenceCandidate,\n type RelationshipInferenceEndpoint,\n type RelationshipInferenceEntity,\n type RelationshipInferenceRelease\n} from \"./relationshipInference.js\"\n\nconst MAXIMUM_INFERENCE_ENTITIES = 500\nconst MAXIMUM_INFERENCE_RELEASES = 50\nconst MAXIMUM_INFERENCE_RELATIONSHIPS = 2_000\nconst COMPONENT = \"relationship-inference\"\n\nexport interface RelationshipInferenceMaterializationScope {\n readonly committedAt: UtcTimestamp\n readonly streamKey: PluginStreamKey\n readonly successfulHealth: Extract<PluginHealth, { readonly _tag: \"healthy\" | \"degraded\" }>\n readonly workspaceId: WorkspaceId\n}\n\nexport interface RelationshipInferenceMaterializationReceipt {\n readonly evidenceClaimCount: number\n readonly evidenceItemCount: number\n readonly nodeCount: number\n readonly relationshipCount: number\n readonly skippedDueToBounds: boolean\n}\n\ntype StableIdentity<IdentityError> = (identity: string) => Effect.Effect<string, IdentityError>\n\nconst readRelationship = Effect.fn(\"RelationshipInferenceMaterialization.readRelationship\")(function*(\n persistence: PersistenceService,\n workspaceId: WorkspaceId,\n relationshipId: RelationshipId\n) {\n const result = yield* persistence.deliveryGraph\n .read(workspaceId, {\n _tag: \"relationship\",\n relationshipId,\n revision: null\n })\n .pipe(Effect.result)\n if (Result.isFailure(result)) {\n if (result.failure._tag === \"RecordNotFoundError\") return null\n return yield* result.failure\n }\n return result.success._tag === \"relationship\" ? result.success.value : null\n})\n\nconst nodeExists = Effect.fn(\"RelationshipInferenceMaterialization.nodeExists\")(function*(\n persistence: PersistenceService,\n workspaceId: WorkspaceId,\n nodeId: GraphNodeId\n) {\n const result = yield* persistence.deliveryGraph\n .read(workspaceId, {\n _tag: \"node\",\n nodeId\n })\n .pipe(Effect.result)\n if (Result.isSuccess(result)) return true\n if (result.failure._tag === \"RecordNotFoundError\") return false\n return yield* result.failure\n})\n\nconst writeGraph = Effect.fn(\"RelationshipInferenceMaterialization.writeGraph\")(function*(\n persistence: PersistenceService,\n workspaceId: WorkspaceId,\n batch: typeof DeliveryGraphWriteBatch.Type\n) {\n const encoded = yield* Schema.encodeEffect(DeliveryGraphWriteBatch)(batch).pipe(\n Effect.mapError(() => new PersistenceOperationError({ operation: \"relationship-inference.encode\" }))\n )\n return yield* persistence.deliveryGraph.write(workspaceId, encoded)\n})\n\nconst relationshipIdentity = (workspaceId: WorkspaceId, identityKey: string): string =>\n `${workspaceId}\\u0000relationship-inference\\u0000relationship\\u0000${identityKey}`\n\nconst missingNodeIdentity = (workspaceId: WorkspaceId, endpointKind: string, missingKey: string): string =>\n `${workspaceId}\\u0000relationship-inference\\u0000missing-node\\u0000${endpointKind}\\u0000${missingKey}`\n\nconst evidenceIdentity = (\n workspaceId: WorkspaceId,\n identityKey: string,\n observationKey: string,\n kind: \"claim\" | \"item\"\n): string =>\n `${workspaceId}\\u0000relationship-inference\\u0000evidence-${kind}\\u0000${identityKey}\\u0000${observationKey}`\n\nconst entityNodeIdentity = (workspaceId: WorkspaceId, entity: EntityRecord): string => {\n const source = entity.sourceRevision\n return `${workspaceId}\\u0000${source.pluginConnectionId}\\u0000${source.providerId}\\u0000entity-node\\u0000${source.vendorImmutableId}`\n}\n\nconst releaseNodeIdentity = (\n workspaceId: WorkspaceId,\n pluginConnectionId: string,\n providerId: string,\n vendorImmutableId: string\n): string => `${workspaceId}\\u0000${pluginConnectionId}\\u0000${providerId}\\u0000release-node\\u0000${vendorImmutableId}`\n\nconst relationshipIdFor = <IdentityError>(\n identity: StableIdentity<IdentityError>,\n workspaceId: WorkspaceId,\n identityKey: string\n) => identity(relationshipIdentity(workspaceId, identityKey)).pipe(Effect.map(RelationshipId.make))\n\nconst endpointNode = <IdentityError>(\n identity: StableIdentity<IdentityError>,\n scope: RelationshipInferenceMaterializationScope,\n endpoint: RelationshipInferenceEndpoint\n) =>\n endpoint._tag === \"resolved\"\n ? Effect.succeed({ node: null, nodeId: endpoint.nodeId })\n : identity(missingNodeIdentity(scope.workspaceId, endpoint.kind, endpoint.identityKey)).pipe(\n Effect.map((value) => {\n const nodeId = GraphNodeId.make(value)\n const node: DeliveryNode = {\n workspaceId: scope.workspaceId,\n nodeId,\n endpointKind: endpoint.kind,\n resolution: {\n _tag: \"missing\",\n expectedKind: \"entity\",\n expectedEntityKind: endpoint.kind,\n missingKey: endpoint.missingKey\n },\n createdAt: scope.committedAt\n }\n return {\n nodeId,\n node\n }\n })\n )\n\nconst evidenceFor = Effect.fn(\"RelationshipInferenceMaterialization.evidenceFor\")(function*<IdentityError>(\n persistence: PersistenceService,\n identity: StableIdentity<IdentityError>,\n scope: RelationshipInferenceMaterializationScope,\n candidate: RelationshipInferenceCandidate,\n sourceNodeId: GraphNodeId,\n targetNodeId: GraphNodeId,\n entity: EntityRecord\n): Effect.fn.Return<\n { readonly claim: EvidenceClaim; readonly item: EvidenceItem },\n IdentityError | PersistenceOperationFailure\n> {\n const evidenceId = EvidenceId.make(\n yield* identity(evidenceIdentity(scope.workspaceId, candidate.identityKey, candidate.observationKey, \"item\"))\n )\n const evidenceClaimId = EvidenceClaimId.make(\n yield* identity(evidenceIdentity(scope.workspaceId, candidate.identityKey, candidate.observationKey, \"claim\"))\n )\n const source = entity.sourceRevision\n const sourceStreamKey = yield* Schema.decodeUnknownEffect(PluginStreamKey)(\n firstPartySyncStreamKey(source.providerId)\n ).pipe(Effect.mapError(() => new PersistenceOperationError({ operation: \"relationship-inference.source-stream\" })))\n const pluginHealth = yield* persistence.pluginRuntime.getLastSuccessfulHealth(\n scope.workspaceId,\n source.pluginConnectionId,\n sourceStreamKey\n )\n if (pluginHealth === null) {\n return yield* new PersistenceOperationError({ operation: \"relationship-inference.source-health\" })\n }\n const sourceAgeSeconds = Math.max(\n 0,\n (DateTime.toEpochMillis(scope.committedAt) - DateTime.toEpochMillis(source.lastObservedAt)) / 1_000\n )\n return {\n item: {\n workspaceId: scope.workspaceId,\n evidenceId,\n schemaVersion: 1,\n attribution: { _tag: \"system\", component: COMPONENT },\n verifier: { _tag: \"system\", component: COMPONENT },\n observedAt: source.lastObservedAt,\n recordedAt: scope.committedAt,\n validUntil: null,\n freshness: {\n _tag: \"current\",\n evaluatedAt: scope.committedAt,\n pluginHealth,\n provenance: { _tag: \"provider\", sourceRevision: source },\n sourceObservedAt: source.lastObservedAt,\n staleAfterSeconds: Math.max(1, Math.ceil(sourceAgeSeconds) + 86_400),\n synchronizedAt: source.synchronizedAt\n },\n retention: { classification: \"evidence\", retainUntil: null, legalHold: false }\n },\n claim: {\n workspaceId: scope.workspaceId,\n evidenceClaimId,\n evidenceId,\n subjectNodeId: sourceNodeId,\n predicate: \"relationship-observed\",\n value: { _tag: \"reference\", targetNodeId },\n recordedAt: scope.committedAt,\n supersedesEvidenceClaimId: null\n }\n }\n})\n\nconst unchanged = (\n previous: DeliveryRelationship | null,\n candidate: RelationshipInferenceCandidate,\n sourceNodeId: GraphNodeId,\n targetNodeId: GraphNodeId,\n claimId: EvidenceClaimId | null\n): boolean =>\n previous !== null &&\n previous.kind === candidate.kind &&\n previous.sourceNodeId === sourceNodeId &&\n previous.targetNodeId === targetNodeId &&\n previous.scope?._tag === \"release\" &&\n previous.scope.releaseId === candidate.releaseId &&\n previous.lifecycle._tag === candidate.lifecycle &&\n (claimId === null || previous.evidenceClaimIds.includes(claimId))\n\nconst protectedByDecision = (previous: DeliveryRelationship | null): boolean =>\n previous?.lifecycle._tag === \"governed\" ||\n previous?.lifecycle._tag === \"verified\" ||\n previous?.lifecycle._tag === \"rejected\"\n\nconst materializeCandidate = Effect.fn(\"RelationshipInferenceMaterialization.materializeCandidate\")(function*<\n IdentityError\n>(\n persistence: PersistenceService,\n identity: StableIdentity<IdentityError>,\n scope: RelationshipInferenceMaterializationScope,\n candidate: RelationshipInferenceCandidate,\n entityById: ReadonlyMap<string, EntityRecord>\n): Effect.fn.Return<RelationshipInferenceMaterializationReceipt, IdentityError | PersistenceOperationFailure> {\n const relationshipId = yield* relationshipIdFor(identity, scope.workspaceId, candidate.identityKey)\n const previous = yield* readRelationship(persistence, scope.workspaceId, relationshipId)\n if (protectedByDecision(previous)) {\n return {\n evidenceClaimCount: 0,\n evidenceItemCount: 0,\n nodeCount: 0,\n relationshipCount: 0,\n skippedDueToBounds: false\n }\n }\n const source = yield* endpointNode(identity, scope, candidate.source)\n const target = yield* endpointNode(identity, scope, candidate.target)\n const evidenceEntity = candidate.evidenceEntityId === null\n ? null\n : (entityById.get(candidate.evidenceEntityId) ?? null)\n const evidence = evidenceEntity === null\n ? null\n : yield* evidenceFor(persistence, identity, scope, candidate, source.nodeId, target.nodeId, evidenceEntity)\n if (unchanged(previous, candidate, source.nodeId, target.nodeId, evidence?.claim.evidenceClaimId ?? null)) {\n return {\n evidenceClaimCount: 0,\n evidenceItemCount: 0,\n nodeCount: 0,\n relationshipCount: 0,\n skippedDueToBounds: false\n }\n }\n const nodes = []\n if (source.node !== null && !(yield* nodeExists(persistence, scope.workspaceId, source.nodeId))) {\n nodes.push(source.node)\n }\n if (target.node !== null && !(yield* nodeExists(persistence, scope.workspaceId, target.nodeId))) {\n nodes.push(target.node)\n }\n const confidence: DeliveryRelationship[\"confidence\"] = candidate.confidence === null\n ? { _tag: \"unknown\", rationale: \"No matching provider evidence is currently synchronized.\" }\n : { _tag: \"inferred\", ...candidate.confidence }\n const relationship: DeliveryRelationship = {\n workspaceId: scope.workspaceId,\n relationshipId,\n relationshipSchemaVersion: 1,\n revision: LedgerRevision.make((previous?.revision ?? 0) + 1),\n supersedesRevision: previous?.revision ?? null,\n kind: candidate.kind,\n sourceNodeId: source.nodeId,\n sourceNodeKind: candidate.source.kind,\n targetNodeId: target.nodeId,\n targetNodeKind: candidate.target.kind,\n scope: { _tag: \"release\", releaseId: candidate.releaseId },\n lifecycle: candidate.lifecycle === \"missing\"\n ? {\n _tag: \"missing\",\n effectiveAt: scope.committedAt,\n reason: \"No synchronized provider evidence currently resolves this required delivery link.\"\n }\n : { _tag: \"inferred\", effectiveAt: scope.committedAt },\n confidence,\n provenance: {\n _tag: \"rule\",\n ruleId: candidate.ruleId,\n ruleVersion: 1,\n rationale: candidate.confidence?.rationale ?? \"Required delivery link has no synchronized match.\"\n },\n recordedBy: { _tag: \"system\", component: COMPONENT },\n evidenceClaimIds: evidence === null ? [] : [evidence.claim.evidenceClaimId],\n recordedAt: scope.committedAt\n }\n const receipt = yield* writeGraph(persistence, scope.workspaceId, {\n entityProjections: [],\n nodes,\n evidenceItems: evidence === null ? [] : [evidence.item],\n evidenceClaims: evidence === null ? [] : [evidence.claim],\n relationships: [relationship]\n })\n return { ...receipt, skippedDueToBounds: false }\n})\n\nconst supersedeObsoleteGap = Effect.fn(\"RelationshipInferenceMaterialization.supersedeObsoleteGap\")(function*<\n IdentityError\n>(\n persistence: PersistenceService,\n identity: StableIdentity<IdentityError>,\n scope: RelationshipInferenceMaterializationScope,\n identityKey: string\n): Effect.fn.Return<number, IdentityError | PersistenceOperationFailure> {\n const relationshipId = yield* relationshipIdFor(identity, scope.workspaceId, identityKey)\n const previous = yield* readRelationship(persistence, scope.workspaceId, relationshipId)\n if (previous?.lifecycle._tag !== \"missing\") return 0\n const relationship: DeliveryRelationship = {\n ...previous,\n revision: LedgerRevision.make(previous.revision + 1),\n supersedesRevision: previous.revision,\n lifecycle: {\n _tag: \"superseded\",\n effectiveAt: scope.committedAt,\n reason: \"New synchronized evidence resolved the previously missing link.\"\n },\n recordedAt: scope.committedAt\n }\n return (yield* writeGraph(persistence, scope.workspaceId, {\n entityProjections: [],\n nodes: [],\n evidenceItems: [],\n evidenceClaims: [],\n relationships: [relationship]\n })).relationshipCount\n})\n\nconst supersedeObsoleteRelationship = Effect.fn(\"RelationshipInferenceMaterialization.supersedeObsoleteRelationship\")(\n function*(\n persistence: PersistenceService,\n scope: RelationshipInferenceMaterializationScope,\n relationshipId: RelationshipId,\n reason?: string\n ) {\n const previous = yield* readRelationship(persistence, scope.workspaceId, relationshipId)\n if (previous?.lifecycle._tag !== \"inferred\" && previous?.lifecycle._tag !== \"missing\") return 0\n const relationship: DeliveryRelationship = {\n ...previous,\n revision: LedgerRevision.make(previous.revision + 1),\n supersedesRevision: previous.revision,\n lifecycle: {\n _tag: \"superseded\",\n effectiveAt: scope.committedAt,\n reason: reason ?? (previous.lifecycle._tag === \"missing\"\n ? \"The entity is no longer in the release scope that required this missing link.\"\n : \"Current synchronized metadata no longer supports this inferred link.\")\n },\n recordedAt: scope.committedAt\n }\n return (yield* writeGraph(persistence, scope.workspaceId, {\n entityProjections: [],\n nodes: [],\n evidenceItems: [],\n evidenceClaims: [],\n relationships: [relationship]\n })).relationshipCount\n }\n)\n\nconst emptyReceipt = (skippedDueToBounds: boolean): RelationshipInferenceMaterializationReceipt => ({\n evidenceClaimCount: 0,\n evidenceItemCount: 0,\n nodeCount: 0,\n relationshipCount: 0,\n skippedDueToBounds\n})\n\nconst retireInferenceForReleases = Effect.fn(\n \"RelationshipInferenceMaterialization.retireInferenceForReleases\"\n)(function*(\n persistence: PersistenceService,\n scope: RelationshipInferenceMaterializationScope,\n releaseIds: ReadonlyArray<RelationshipInferenceRelease[\"releaseId\"]> | null,\n reason: string\n) {\n const reads = yield* Effect.forEach(\n releaseIds ?? [null],\n (releaseId) =>\n persistence.deliveryGraph.read(scope.workspaceId, {\n _tag: \"componentRelationships\",\n releaseId,\n component: COMPONENT,\n limit: MAXIMUM_INFERENCE_RELATIONSHIPS\n })\n )\n if (\n reads.some((read) => read._tag !== \"componentRelationships\" || read.value.truncated)\n ) return emptyReceipt(true)\n const relationshipIds = new Set(\n reads.flatMap((read) =>\n read._tag === \"componentRelationships\"\n ? read.value.relationships.map(({ relationshipId }) => relationshipId)\n : []\n )\n )\n let relationshipCount = 0\n for (const relationshipId of relationshipIds) {\n relationshipCount += yield* supersedeObsoleteRelationship(\n persistence,\n scope,\n relationshipId,\n reason\n )\n }\n return { ...emptyReceipt(true), relationshipCount }\n})\n\nconst retireInferenceAtEntityBound = Effect.fn(\n \"RelationshipInferenceMaterialization.retireInferenceAtEntityBound\"\n)(function*(\n persistence: PersistenceService,\n scope: RelationshipInferenceMaterializationScope\n) {\n return yield* retireInferenceForReleases(\n persistence,\n scope,\n null,\n \"Inference inputs exceeded the bounded workspace snapshot, so this relationship can no longer be proven.\"\n )\n})\n\n/** Persist current rule candidates after a normalized page has committed. */\nexport const materializeRelationshipInference = Effect.fn(\"RelationshipInferenceMaterialization.reconcile\")(function*<\n IdentityError\n>(\n persistence: PersistenceService,\n identity: StableIdentity<IdentityError>,\n scope: RelationshipInferenceMaterializationScope\n): Effect.fn.Return<RelationshipInferenceMaterializationReceipt, IdentityError | PersistenceOperationFailure> {\n const projectionResult = yield* persistence.deliveryGraph.read(scope.workspaceId, {\n _tag: \"workspaceEntityProjections\",\n owner: null,\n query: null,\n service: null,\n status: null,\n type: null,\n limit: MAXIMUM_INFERENCE_ENTITIES\n })\n if (projectionResult._tag !== \"workspaceEntityProjections\") return emptyReceipt(true)\n if (projectionResult.value.truncated) return yield* retireInferenceAtEntityBound(persistence, scope)\n const records = yield* Effect.forEach(\n projectionResult.value.items,\n ({ projection }) => persistence.entities.get(scope.workspaceId, projection.entityId),\n { concurrency: 10 }\n )\n const entityById = new Map(records.map((record) => [record.entityId, record]))\n const entities: Array<RelationshipInferenceEntity> = []\n for (const item of projectionResult.value.items) {\n const entity = entityById.get(item.projection.entityId)\n if (entity === undefined) continue\n entities.push({\n projection: item.projection,\n releaseIds: item.releaseIds,\n nodeId: GraphNodeId.make(yield* identity(entityNodeIdentity(scope.workspaceId, entity)))\n })\n }\n const releases = yield* persistence.releases.list(scope.workspaceId, MAXIMUM_INFERENCE_RELEASES + 1)\n if (releases.length > MAXIMUM_INFERENCE_RELEASES) {\n return yield* retireInferenceAtEntityBound(persistence, scope)\n }\n const inferenceReleases: Array<{\n readonly inferenceRelease: RelationshipInferenceRelease\n readonly node: DeliveryNode | null\n }> = []\n for (const { release } of releases) {\n const candidates = yield* Effect.forEach(release.sourceRevisions, (source) =>\n Effect.gen(function*() {\n const nodeId = GraphNodeId.make(\n yield* identity(\n releaseNodeIdentity(\n scope.workspaceId,\n source.pluginConnectionId,\n source.providerId,\n source.vendorImmutableId\n )\n )\n )\n return { exists: yield* nodeExists(persistence, scope.workspaceId, nodeId), nodeId }\n }))\n const selected = candidates.find(({ exists }) => exists) ?? candidates[0]\n if (selected === undefined) continue\n inferenceReleases.push({\n inferenceRelease: { nodeId: selected.nodeId, releaseId: release.id, version: release.version },\n node: selected.exists\n ? null\n : {\n workspaceId: scope.workspaceId,\n nodeId: selected.nodeId,\n endpointKind: \"release\",\n resolution: { _tag: \"resolved\", target: { _tag: \"release\", releaseId: release.id } },\n createdAt: scope.committedAt\n }\n })\n }\n const releaseIds = releases.map(({ release }) => release.id)\n const slices = yield* Effect.forEach(releaseIds, (releaseId) =>\n persistence.deliveryGraph.read(scope.workspaceId, {\n _tag: \"releaseSlice\",\n releaseId,\n environmentId: null,\n limit: MAXIMUM_INFERENCE_ENTITIES\n }))\n const truncatedReleaseIds = slices.flatMap((slice, index) => {\n const releaseId = releaseIds[index]\n return releaseId !== undefined && (slice._tag !== \"releaseSlice\" || slice.value.truncated) ? [releaseId] : []\n })\n if (truncatedReleaseIds.length > 0) {\n return yield* retireInferenceForReleases(\n persistence,\n scope,\n truncatedReleaseIds,\n \"The bounded release relationship snapshot was incomplete, so this inference can no longer be proven.\"\n )\n }\n const relationships = slices.flatMap((slice) => (slice._tag === \"releaseSlice\" ? slice.value.relationships : []))\n const inferenceInput = {\n entities,\n releases: inferenceReleases.map(({ inferenceRelease }) => inferenceRelease),\n relationships\n }\n const initialInference = deriveRelationshipInference(inferenceInput)\n const rejectedCandidateIdentityKeys = new Set<string>()\n for (const candidate of initialInference.candidates) {\n if (candidate.lifecycle !== \"inferred\") continue\n const relationshipId = yield* relationshipIdFor(identity, scope.workspaceId, candidate.identityKey)\n const previous = yield* readRelationship(persistence, scope.workspaceId, relationshipId)\n if (previous?.lifecycle._tag === \"rejected\") rejectedCandidateIdentityKeys.add(candidate.identityKey)\n }\n const inference = rejectedCandidateIdentityKeys.size === 0\n ? initialInference\n : deriveRelationshipInference({ ...inferenceInput, rejectedCandidateIdentityKeys })\n if (inference.truncated) return yield* retireInferenceAtEntityBound(persistence, scope)\n let receipt = emptyReceipt(false)\n const missingReleaseNodes = inferenceReleases.flatMap(({ node }) => node === null ? [] : [node])\n if (missingReleaseNodes.length > 0) {\n const current = yield* writeGraph(persistence, scope.workspaceId, {\n entityProjections: [],\n nodes: missingReleaseNodes,\n evidenceItems: [],\n evidenceClaims: [],\n relationships: []\n })\n receipt = { ...receipt, nodeCount: current.nodeCount }\n }\n for (const candidate of inference.candidates) {\n const current = yield* materializeCandidate(persistence, identity, scope, candidate, entityById)\n receipt = {\n evidenceClaimCount: receipt.evidenceClaimCount + current.evidenceClaimCount,\n evidenceItemCount: receipt.evidenceItemCount + current.evidenceItemCount,\n nodeCount: receipt.nodeCount + current.nodeCount,\n relationshipCount: receipt.relationshipCount + current.relationshipCount,\n skippedDueToBounds: false\n }\n }\n for (const identityKey of inference.obsoleteGapIdentityKeys) {\n receipt = {\n ...receipt,\n relationshipCount: receipt.relationshipCount +\n (yield* supersedeObsoleteGap(persistence, identity, scope, identityKey))\n }\n }\n for (const relationshipId of inference.obsoleteRelationshipIds) {\n receipt = {\n ...receipt,\n relationshipCount: receipt.relationshipCount +\n (yield* supersedeObsoleteRelationship(persistence, scope, relationshipId))\n }\n }\n return receipt\n})\n","import * as Crypto from \"effect/Crypto\"\nimport * as DateTime from \"effect/DateTime\"\nimport * as Effect from \"effect/Effect\"\nimport * as Encoding from \"effect/Encoding\"\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\n\nimport { derivePersonInitials, Person } from \"../../domain/actors.js\"\nimport {\n type DeliveryEntityDetails,\n type DeliveryEntityKind,\n type DeliveryNode,\n type DeliveryRelationship,\n EvidencePredicate,\n EvidenceValue,\n LedgerRevision,\n RelationshipKind\n} from \"../../domain/deliveryGraph.js\"\nimport type { PluginHealth } from \"../../domain/freshness.js\"\nimport {\n EntityId,\n EnvironmentId,\n EvidenceClaimId,\n EvidenceId,\n GraphNodeId,\n PersonId,\n type PluginConnectionId,\n RelationshipId,\n ReleaseId,\n type WorkspaceId\n} from \"../../domain/identifiers.js\"\nimport { NormalizedIssueAttributes } from \"../../domain/normalizedIssue.js\"\nimport type { NormalizedPluginEventV1, PluginSyncPageV1 } from \"../../domain/plugins/events.js\"\nimport { Release } from \"../../domain/release.js\"\nimport { deriveReleaseRelay } from \"../../domain/releaseRelay.js\"\nimport { NormalizationSchemaVersion, type ProviderId, VendorImmutableId } from \"../../domain/sourceRevision.js\"\nimport type { UtcTimestamp } from \"../../domain/utcTimestamp.js\"\nimport type { PersistenceOperationFailure, PersistenceService } from \"../persistence/Persistence.js\"\nimport { Persistence } from \"../persistence/Persistence.js\"\nimport { DeliveryGraphWriteBatch } from \"../persistence/repositories/deliveryGraphRepository.js\"\nimport type { EntityRecord } from \"../persistence/repositories/models.js\"\nimport type { PluginStreamKey } from \"../persistence/repositories/pluginRuntimeModels.js\"\nimport type { PluginConflictFailure } from \"../plugins/failures.js\"\nimport {\n type PluginSynchronizationAuthority,\n verifyPluginSynchronizationAuthority\n} from \"./pluginSynchronizationAuthority.js\"\nimport { materializeRelationshipInference } from \"./relationshipInferenceMaterialization.js\"\n\ntype EntityUpsert = Extract<NormalizedPluginEventV1, { readonly _tag: \"UpsertEntity\" }>\ntype EntityTombstone = Extract<NormalizedPluginEventV1, { readonly _tag: \"TombstoneEntity\" }>\ntype EvidenceAppend = Extract<NormalizedPluginEventV1, { readonly _tag: \"AppendEvidence\" }>\ntype PersonUpsert = Extract<NormalizedPluginEventV1, { readonly _tag: \"UpsertPerson\" }>\ntype RelationshipProposal = Extract<NormalizedPluginEventV1, { readonly _tag: \"ProposeRelationship\" }>\n\ninterface RelationshipEndpointResolution {\n readonly entity: EntityRecord | null\n readonly kind: DeliveryRelationship[\"sourceNodeKind\"]\n readonly node: DeliveryNode | null\n readonly nodeId: GraphNodeId\n readonly releaseId: ReleaseId | null\n}\n\nconst OptionalText = Schema.optionalKey(Schema.NullOr(Schema.String))\nconst NamedText = Schema.Union([\n Schema.String,\n Schema.Struct({ name: Schema.optionalKey(Schema.NullOr(Schema.String)) })\n])\nconst EntityAttributes = Schema.Struct({\n key: OptionalText,\n status: Schema.optionalKey(Schema.NullOr(NamedText)),\n priority: Schema.optionalKey(Schema.NullOr(NamedText)),\n estimatePoints: Schema.optionalKey(Schema.NullOr(Schema.Number)),\n repository: OptionalText,\n sourceBranch: OptionalText,\n targetBranch: OptionalText,\n headRevision: OptionalText,\n reviewState: OptionalText,\n spaceKey: OptionalText,\n spaceId: OptionalText,\n currentVersion: Schema.optionalKey(Schema.NullOr(Schema.Number)),\n linkedIssueKeys: Schema.optionalKey(Schema.Array(Schema.String)),\n linkedReleaseVersions: Schema.optionalKey(Schema.Array(Schema.String)),\n pipelineName: OptionalText,\n executionId: OptionalText,\n triggerRevision: OptionalText,\n sourceRevisions: Schema.optionalKey(Schema.Array(Schema.Struct({ revisionId: OptionalText }))),\n environmentId: OptionalText,\n revision: OptionalText,\n durationMinutes: Schema.optionalKey(Schema.NullOr(Schema.Number)),\n billable: Schema.optionalKey(Schema.Boolean),\n approvalState: OptionalText,\n interval: Schema.optionalKey(Schema.Struct({\n duration: OptionalText,\n state: OptionalText\n }))\n})\nconst LegacyIssueAttributes = Schema.Struct({\n key: OptionalText,\n status: Schema.optionalKey(Schema.NullOr(NamedText)),\n priority: Schema.optionalKey(Schema.NullOr(NamedText)),\n estimatePoints: Schema.optionalKey(Schema.NullOr(Schema.Number))\n})\nconst LegacyIssueAttributeKeys: ReadonlySet<string> = new Set([\n \"key\",\n \"status\",\n \"priority\",\n \"estimatePoints\",\n \"schemaVersion\",\n \"summary\"\n])\nconst ReleaseAttributes = Schema.Struct({\n serviceName: Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(200)),\n version: Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(100)),\n lifecycle: Schema.Literals([\"assembling\", \"candidate\", \"deploying\", \"released\", \"cancelled\"])\n})\nconst JiraIssueRelationshipSnapshot = Schema.Struct({\n fixVersions: Schema.Array(Schema.Struct({\n sourceId: Schema.NullOr(Schema.String)\n })),\n truncatedFields: Schema.Array(Schema.String)\n})\nconst EvidenceData = Schema.Struct({\n predicate: Schema.optionalKey(EvidencePredicate),\n value: Schema.optionalKey(EvidenceValue)\n})\n\n/** Redacted failure raised before a normalized page can become a canonical projection. */\nexport class NormalizedPluginPageMaterializationError extends Schema.TaggedErrorClass<\n NormalizedPluginPageMaterializationError\n>()(\"NormalizedPluginPageMaterializationError\", {\n diagnosticCode: Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(100)),\n eventId: Schema.NullOr(Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(512)))\n}) {}\n\nconst malformed = (diagnosticCode: string, eventId: string | null = null) =>\n new NormalizedPluginPageMaterializationError({ diagnosticCode, eventId })\n\nconst decodedAttributes = Effect.fn(\"NormalizedPluginPageMaterialization.decodeAttributes\")(function*(\n event: EntityUpsert\n) {\n return yield* Schema.decodeUnknownEffect(EntityAttributes)(event.attributes).pipe(\n Effect.mapError(() => malformed(\"normalized-entity-attributes-invalid\", event.eventId))\n )\n})\n\nconst bounded = (value: string | null | undefined, fallback: string, maximum: number): string => {\n const normalized = value?.trim()\n return (normalized === undefined || normalized.length === 0 ? fallback : normalized).slice(0, maximum)\n}\n\nconst namedText = (value: typeof NamedText.Type | null | undefined): string | null =>\n typeof value === \"string\" ? value : (value?.name ?? null)\n\nconst decodedIssueAttributes = Effect.fn(\"NormalizedPluginPageMaterialization.decodeIssueAttributes\")(function*(\n event: EntityUpsert\n) {\n const normalized = Schema.decodeUnknownResult(NormalizedIssueAttributes)(event.attributes)\n if (Result.isSuccess(normalized)) return normalized.success\n if (Object.keys(event.attributes).some((key) => !LegacyIssueAttributeKeys.has(key))) {\n return yield* malformed(\"normalized-issue-attributes-invalid\", event.eventId)\n }\n\n const legacy = yield* Schema.decodeUnknownEffect(LegacyIssueAttributes)(event.attributes).pipe(\n Effect.mapError(() => malformed(\"normalized-issue-attributes-invalid\", event.eventId))\n )\n const key = bounded(legacy.key, event.vendorImmutableId, 100)\n return yield* Schema.decodeUnknownEffect(NormalizedIssueAttributes)({\n key,\n status: bounded(namedText(legacy.status), \"unknown\", 100),\n priority: legacy.priority === null || legacy.priority === undefined\n ? null\n : bounded(namedText(legacy.priority), \"unknown\", 100),\n estimatePoints: legacy.estimatePoints ?? null\n }).pipe(Effect.mapError(() => malformed(\"normalized-issue-attributes-invalid\", event.eventId)))\n})\n\nconst canonicalKind = (entityType: string): typeof DeliveryEntityKind.Type | null => {\n switch (entityType) {\n case \"issue\":\n case \"jira.issue\":\n return \"issue\"\n case \"pull-request\":\n return \"pull-request\"\n case \"page\":\n case \"confluence-page\":\n return \"page\"\n case \"pipeline-execution\":\n case \"aws.codepipeline.execution\":\n return \"pipeline-execution\"\n case \"deployment\":\n return \"deployment\"\n case \"time-entry\":\n case \"clockify.time-entry\":\n return \"time-entry\"\n default:\n return null\n }\n}\n\nconst reviewState = (\n value: string | null | undefined\n): \"approved\" | \"changes-requested\" | \"merged\" | \"not-requested\" | \"requested\" => {\n switch (value?.toLowerCase()) {\n case \"requested\":\n case \"open\":\n return \"requested\"\n case \"changes-requested\":\n case \"changes requested\":\n return \"changes-requested\"\n case \"approved\":\n return \"approved\"\n case \"merged\":\n case \"closed\":\n return \"merged\"\n default:\n return \"not-requested\"\n }\n}\n\nconst pipelineStatus = (\n value: string | null | undefined\n): \"failed\" | \"queued\" | \"running\" | \"stopped\" | \"succeeded\" => {\n switch (value?.toLowerCase()) {\n case \"inprogress\":\n case \"in-progress\":\n case \"running\":\n return \"running\"\n case \"succeeded\":\n case \"success\":\n return \"succeeded\"\n case \"failed\":\n case \"failure\":\n return \"failed\"\n case \"stopped\":\n case \"stopping\":\n case \"superseded\":\n case \"abandoned\":\n return \"stopped\"\n default:\n return \"queued\"\n }\n}\n\nconst isoDurationMinutes = (value: string | null | undefined): number => {\n if (value === null || value === undefined) return 0\n const match = /^PT(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?$/u.exec(value)\n if (match === null) return 0\n const hours = Number(match[1] ?? 0)\n const minutes = Number(match[2] ?? 0)\n const seconds = Number(match[3] ?? 0)\n return Math.max(0, Math.round(hours * 60 + minutes + seconds / 60))\n}\n\nconst entityPresentation = Effect.fn(\"NormalizedPluginPageMaterialization.entityPresentation\")(function*(\n event: EntityUpsert,\n kind: typeof DeliveryEntityKind.Type\n): Effect.fn.Return<\n { readonly details: DeliveryEntityDetails; readonly displayKey: string },\n NormalizedPluginPageMaterializationError\n> {\n const attributes = yield* decodedAttributes(event)\n switch (kind) {\n case \"issue\": {\n const issueAttributes = yield* decodedIssueAttributes(event)\n return {\n displayKey: issueAttributes.key,\n details: {\n _tag: \"issue\",\n ...issueAttributes\n }\n }\n }\n case \"pull-request\":\n return {\n displayKey: bounded(event.vendorImmutableId, event.vendorImmutableId, 200),\n details: {\n _tag: \"pull-request\",\n repository: bounded(attributes.repository, \"unknown\", 200),\n sourceBranch: bounded(attributes.sourceBranch, \"unknown\", 500),\n targetBranch: bounded(attributes.targetBranch, \"unknown\", 500),\n headRevision: bounded(attributes.headRevision, event.revision, 512),\n reviewState: reviewState(attributes.reviewState ?? namedText(attributes.status))\n }\n }\n case \"page\":\n return {\n displayKey: bounded(event.vendorImmutableId, event.vendorImmutableId, 200),\n details: {\n _tag: \"page\",\n spaceKey: bounded(attributes.spaceKey ?? attributes.spaceId, \"unknown\", 100),\n revision: bounded(\n attributes.currentVersion === null || attributes.currentVersion === undefined\n ? attributes.revision\n : String(attributes.currentVersion),\n event.revision,\n 512\n ),\n status: namedText(attributes.status)?.toLowerCase() === \"superseded\" ? \"superseded\" : \"current\",\n linkedIssueKeys: attributes.linkedIssueKeys\n ?.map((key) => key.trim())\n .filter((key, index, keys) => key.length > 0 && key.length <= 100 && keys.indexOf(key) === index)\n .slice(0, 100),\n linkedReleaseVersions: attributes.linkedReleaseVersions\n ?.map((version) => version.trim())\n .filter(\n (version, index, versions) =>\n version.length > 0 && version.length <= 100 && versions.indexOf(version) === index\n )\n .slice(0, 100)\n }\n }\n case \"pipeline-execution\": {\n const executionId = bounded(attributes.executionId, event.vendorImmutableId, 512)\n const pipelineName = bounded(attributes.pipelineName, \"unknown\", 200)\n const sourceRevision = attributes.sourceRevisions?.find(({ revisionId }) => revisionId !== null)?.revisionId\n return {\n displayKey: bounded(`${pipelineName}/${executionId}`, executionId, 200),\n details: {\n _tag: \"pipeline-execution\",\n pipelineName,\n executionId,\n status: pipelineStatus(namedText(attributes.status)),\n triggerRevision: bounded(attributes.triggerRevision ?? sourceRevision, event.revision, 512)\n }\n }\n }\n case \"deployment\": {\n const environmentId = yield* Schema.decodeUnknownEffect(EnvironmentId)(attributes.environmentId).pipe(\n Effect.mapError(() => malformed(\"normalized-deployment-environment-invalid\", event.eventId))\n )\n const status = pipelineStatus(namedText(attributes.status))\n return {\n displayKey: bounded(event.vendorImmutableId, event.vendorImmutableId, 200),\n details: {\n _tag: \"deployment\",\n environmentId,\n revision: bounded(attributes.revision, event.revision, 512),\n status: status === \"queued\" ? \"pending\" : status === \"running\" ?\n \"deploying\" :\n status === \"stopped\"\n ? \"rolled-back\"\n : status\n }\n }\n }\n case \"time-entry\":\n return {\n displayKey: bounded(event.vendorImmutableId, event.vendorImmutableId, 200),\n details: {\n _tag: \"time-entry\",\n durationMinutes: Math.max(\n 0,\n Math.round(attributes.durationMinutes ?? isoDurationMinutes(attributes.interval?.duration))\n ),\n billable: attributes.billable ?? false,\n approvalState: attributes.approvalState === \"approved\" || attributes.approvalState === \"rejected\"\n ? attributes.approvalState\n : attributes.interval?.state === \"running\"\n ? \"pending\"\n : \"not-required\"\n }\n }\n }\n})\n\nconst stableUuid = Effect.fn(\"NormalizedPluginPageMaterialization.stableUuid\")(function*(\n cryptoService: Crypto.Crypto,\n identity: string,\n eventId: string\n) {\n const bytes = yield* Effect.fromResult(Encoding.decodeBase64(Encoding.encodeBase64(identity))).pipe(\n Effect.mapError(() => malformed(\"normalized-identity-encoding-failed\", eventId))\n )\n const digest = yield* cryptoService.digest(\"SHA-256\", bytes).pipe(\n Effect.mapError(() => malformed(\"normalized-identity-digest-failed\", eventId))\n )\n const hex = Encoding.encodeHex(digest)\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-7${hex.slice(13, 16)}-8${hex.slice(17, 20)}-${hex.slice(20, 32)}`\n})\n\nconst sourceIdentity = (\n scope: NormalizedPluginPageMaterializationScope,\n vendorImmutableId: typeof VendorImmutableId.Type\n) => ({\n pluginConnectionId: scope.pluginConnectionId,\n providerId: scope.providerId,\n vendorImmutableId\n})\n\nconst findEntity = Effect.fn(\"NormalizedPluginPageMaterialization.findEntity\")(function*(\n persistence: PersistenceService,\n scope: NormalizedPluginPageMaterializationScope,\n vendorImmutableId: typeof VendorImmutableId.Type\n) {\n const found = yield* persistence.entities.findBySourceIdentity(\n scope.workspaceId,\n sourceIdentity(scope, vendorImmutableId)\n ).pipe(Effect.result)\n if (Result.isSuccess(found)) return found.success\n if (found.failure._tag === \"RecordNotFoundError\") return null\n return yield* found.failure\n})\n\nconst readProjection = Effect.fn(\"NormalizedPluginPageMaterialization.readProjection\")(function*(\n persistence: PersistenceService,\n workspaceId: WorkspaceId,\n entityId: EntityId\n) {\n const found = yield* persistence.deliveryGraph.read(workspaceId, {\n _tag: \"entityProjection\",\n entityId,\n revision: null\n }).pipe(Effect.result)\n if (Result.isSuccess(found)) {\n return found.success._tag === \"entityProjection\" ? found.success.value : null\n }\n if (found.failure._tag === \"RecordNotFoundError\") return null\n return yield* found.failure\n})\n\nconst materializationKey = (\n scope: NormalizedPluginPageMaterializationScope,\n kind: string,\n externalId: string\n) => `${scope.workspaceId}\\u0000${scope.pluginConnectionId}\\u0000${scope.providerId}\\u0000${kind}\\u0000${externalId}`\n\nconst entityIdFor = Effect.fn(\"NormalizedPluginPageMaterialization.entityIdFor\")(function*(\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n vendorImmutableId: string,\n eventId: string\n) {\n return EntityId.make(\n yield* stableUuid(\n cryptoService,\n materializationKey(scope, \"entity\", vendorImmutableId),\n eventId\n )\n )\n})\n\nconst nodeIdFor = Effect.fn(\"NormalizedPluginPageMaterialization.nodeIdFor\")(function*(\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n vendorImmutableId: string,\n eventId: string\n) {\n return GraphNodeId.make(\n yield* stableUuid(cryptoService, materializationKey(scope, \"entity-node\", vendorImmutableId), eventId)\n )\n})\n\nconst releaseIdFor = Effect.fn(\"NormalizedPluginPageMaterialization.releaseIdFor\")(function*(\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n vendorImmutableId: string,\n eventId: string\n) {\n return ReleaseId.make(\n yield* stableUuid(\n cryptoService,\n materializationKey(scope, \"release\", vendorImmutableId),\n eventId\n )\n )\n})\n\nconst releaseNodeIdFor = Effect.fn(\"NormalizedPluginPageMaterialization.releaseNodeIdFor\")(function*(\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n vendorImmutableId: string,\n eventId: string\n) {\n return GraphNodeId.make(\n yield* stableUuid(\n cryptoService,\n materializationKey(scope, \"release-node\", vendorImmutableId),\n eventId\n )\n )\n})\n\nconst sourceRevision = (\n scope: NormalizedPluginPageMaterializationScope,\n event: EntityUpsert | EntityTombstone,\n firstObservedAt: UtcTimestamp,\n sourceUrl: EntityUpsert[\"sourceUrl\"]\n) => ({\n ...sourceIdentity(scope, event.vendorImmutableId),\n revision: event.revision,\n sourceUrl,\n firstObservedAt,\n lastObservedAt: event.observedAt,\n synchronizedAt: scope.committedAt,\n normalizationSchemaVersion: NormalizationSchemaVersion.make(1)\n})\n\nconst laterTimestamp = (left: UtcTimestamp, right: UtcTimestamp): UtcTimestamp =>\n DateTime.Order(left, right) >= 0 ? left : right\n\nconst sameSourceUrl = (\n left: EntityUpsert[\"sourceUrl\"],\n right: EntityUpsert[\"sourceUrl\"]\n): boolean => left?.href === right?.href\n\nconst writeGraph = Effect.fn(\"NormalizedPluginPageMaterialization.writeGraph\")(function*(\n persistence: PersistenceService,\n workspaceId: WorkspaceId,\n batch: typeof DeliveryGraphWriteBatch.Type,\n eventId: string\n) {\n const encoded = yield* Schema.encodeEffect(DeliveryGraphWriteBatch)(batch).pipe(\n Effect.mapError(() => malformed(\"normalized-delivery-graph-batch-invalid\", eventId))\n )\n return yield* persistence.deliveryGraph.write(workspaceId, encoded)\n})\n\nconst materializeUpsertEntity = Effect.fn(\n \"NormalizedPluginPageMaterialization.upsertEntity\"\n)(function*(\n persistence: PersistenceService,\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n event: EntityUpsert\n) {\n const kind = canonicalKind(event.entityType)\n if (kind === null) return { entityProjectionCount: 0, nodeCount: 0, skippedEntityCount: 1 }\n const presentation = yield* entityPresentation(event, kind)\n const existing = yield* findEntity(persistence, scope, event.vendorImmutableId)\n const entityId = existing?.entityId ??\n (yield* entityIdFor(cryptoService, scope, event.vendorImmutableId, event.eventId))\n const currentProjection = existing === null\n ? null\n : yield* readProjection(persistence, scope.workspaceId, entityId)\n if (\n existing !== null &&\n existing.sourceRevision.revision === event.revision &&\n currentProjection?.projection.entityState === \"present\"\n ) {\n return { entityProjectionCount: 0, nodeCount: 0, skippedEntityCount: 0 }\n }\n\n const persisted = existing === null\n ? yield* persistence.entities.create(scope.workspaceId, {\n entityId,\n entityType: kind,\n sourceRevision: sourceRevision(scope, event, event.observedAt, event.sourceUrl),\n createdAt: scope.committedAt\n })\n : existing.sourceRevision.revision === event.revision\n ? existing\n : yield* persistence.entities.updateSourceRevision(scope.workspaceId, entityId, {\n sourceRevision: sourceRevision(\n scope,\n event,\n existing.sourceRevision.firstObservedAt,\n event.sourceUrl\n ),\n expectedRevision: existing.revision,\n updatedAt: scope.committedAt\n })\n const projectionRevision = LedgerRevision.make((currentProjection?.projection.projectionRevision ?? 0) + 1)\n const nodeId = yield* nodeIdFor(cryptoService, scope, event.vendorImmutableId, event.eventId)\n const batch = {\n entityProjections: [{\n projection: {\n workspaceId: scope.workspaceId,\n entityId,\n projectionRevision,\n sourceEntityRevision: LedgerRevision.make(persisted.revision),\n supersedesProjectionRevision: currentProjection?.projection.projectionRevision ?? null,\n projectionSchemaVersion: 1,\n entityState: \"present\",\n entityType: kind,\n displayKey: presentation.displayKey,\n title: event.title,\n details: presentation.details\n },\n recordedAt: scope.committedAt\n }],\n nodes: currentProjection === null\n ? [{\n workspaceId: scope.workspaceId,\n nodeId,\n endpointKind: kind,\n resolution: { _tag: \"resolved\", target: { _tag: \"entity\", entityId, entityKind: kind } },\n createdAt: scope.committedAt\n }]\n : [],\n evidenceItems: [],\n evidenceClaims: [],\n relationships: []\n } satisfies typeof DeliveryGraphWriteBatch.Type\n const receipt = yield* writeGraph(persistence, scope.workspaceId, batch, event.eventId)\n return { ...receipt, skippedEntityCount: 0 }\n})\n\nconst materializeRelease = Effect.fn(\"NormalizedPluginPageMaterialization.upsertRelease\")(function*(\n persistence: PersistenceService,\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n event: EntityUpsert\n) {\n const attributes = yield* Schema.decodeUnknownEffect(ReleaseAttributes)(event.attributes).pipe(\n Effect.mapError(() => malformed(\"normalized-release-attributes-invalid\", event.eventId))\n )\n const releaseId = yield* releaseIdFor(cryptoService, scope, event.vendorImmutableId, event.eventId)\n const existing = yield* persistence.releases.get(scope.workspaceId, releaseId).pipe(Effect.result)\n if (Result.isFailure(existing) && existing.failure._tag !== \"RecordNotFoundError\") {\n return yield* existing.failure\n }\n const previous = Result.isSuccess(existing) ? existing.success : null\n const previousSource = previous?.release.sourceRevisions.find(\n ({ pluginConnectionId, providerId, vendorImmutableId }) =>\n pluginConnectionId === scope.pluginConnectionId &&\n providerId === scope.providerId &&\n vendorImmutableId === event.vendorImmutableId\n )\n const observedAt = previousSource === undefined\n ? event.observedAt\n : laterTimestamp(previousSource.lastObservedAt, event.observedAt)\n const source = sourceRevision(\n scope,\n event,\n previousSource?.firstObservedAt ?? event.observedAt,\n event.sourceUrl\n )\n const refreshedSource = { ...source, lastObservedAt: observedAt }\n const sourceAgeSeconds = Math.max(\n 0,\n (DateTime.toEpochMillis(scope.committedAt) - DateTime.toEpochMillis(observedAt)) / 1_000\n )\n const release = yield* Schema.decodeUnknownEffect(Schema.toType(Release))({\n createdAt: previous?.release.createdAt ?? event.observedAt,\n freshness: {\n _tag: \"current\",\n evaluatedAt: scope.committedAt,\n pluginHealth: scope.successfulHealth,\n provenance: { _tag: \"provider\", sourceRevision: refreshedSource },\n sourceObservedAt: observedAt,\n staleAfterSeconds: Math.max(1, Math.ceil(sourceAgeSeconds) + 86_400),\n synchronizedAt: scope.committedAt\n },\n id: releaseId,\n lifecycle: attributes.lifecycle,\n relay: deriveReleaseRelay(releaseId),\n roleAssignments: previous?.release.roleAssignments ?? [],\n serviceName: attributes.serviceName,\n sourceRevisions: [\n ...(previous?.release.sourceRevisions.filter(\n ({ pluginConnectionId, providerId, vendorImmutableId }) =>\n pluginConnectionId !== scope.pluginConnectionId ||\n providerId !== scope.providerId ||\n vendorImmutableId !== event.vendorImmutableId\n ) ?? []),\n refreshedSource\n ],\n targetEnvironmentIds: previous?.release.targetEnvironmentIds ?? [],\n updatedAt: scope.committedAt,\n version: attributes.version,\n workspaceId: scope.workspaceId\n }).pipe(Effect.mapError(() => malformed(\"normalized-release-invalid\", event.eventId)))\n if (previous === null) {\n yield* persistence.releases.create(scope.workspaceId, release)\n } else if (\n previousSource === undefined ||\n previousSource.revision !== refreshedSource.revision ||\n !sameSourceUrl(previousSource.sourceUrl, refreshedSource.sourceUrl) ||\n !DateTime.Equivalence(previousSource.lastObservedAt, refreshedSource.lastObservedAt) ||\n !DateTime.Equivalence(previousSource.synchronizedAt, refreshedSource.synchronizedAt) ||\n previous.release.serviceName !== release.serviceName ||\n previous.release.version !== release.version ||\n previous.release.lifecycle !== release.lifecycle\n ) {\n yield* persistence.releases.append(scope.workspaceId, release, previous.revision)\n }\n const nodeId = yield* releaseNodeIdFor(cryptoService, scope, event.vendorImmutableId, event.eventId)\n const existingNode = yield* persistence.deliveryGraph.read(scope.workspaceId, {\n _tag: \"node\",\n nodeId\n }).pipe(Effect.result)\n if (Result.isSuccess(existingNode)) return { nodeCount: 0 }\n if (existingNode.failure._tag !== \"RecordNotFoundError\") return yield* existingNode.failure\n const receipt = yield* writeGraph(persistence, scope.workspaceId, {\n entityProjections: [],\n nodes: [{\n workspaceId: scope.workspaceId,\n nodeId,\n endpointKind: \"release\",\n resolution: { _tag: \"resolved\", target: { _tag: \"release\", releaseId } },\n createdAt: scope.committedAt\n }],\n evidenceItems: [],\n evidenceClaims: [],\n relationships: []\n }, event.eventId)\n return { nodeCount: receipt.nodeCount }\n})\n\nconst materializeTombstoneEntity = Effect.fn(\n \"NormalizedPluginPageMaterialization.tombstoneEntity\"\n)(function*(\n persistence: PersistenceService,\n scope: NormalizedPluginPageMaterializationScope,\n event: EntityTombstone\n) {\n const existing = yield* findEntity(persistence, scope, event.vendorImmutableId)\n if (existing === null) return { entityProjectionCount: 0 }\n const current = yield* readProjection(persistence, scope.workspaceId, existing.entityId)\n if (current === null) return yield* malformed(\"normalized-tombstone-projection-missing\", event.eventId)\n if (existing.sourceRevision.revision === event.revision && current.projection.entityState === \"deleted\") {\n return { entityProjectionCount: 0 }\n }\n const persisted = existing.sourceRevision.revision === event.revision\n ? existing\n : yield* persistence.entities.updateSourceRevision(scope.workspaceId, existing.entityId, {\n sourceRevision: sourceRevision(\n scope,\n event,\n existing.sourceRevision.firstObservedAt,\n existing.sourceRevision.sourceUrl\n ),\n expectedRevision: existing.revision,\n updatedAt: scope.committedAt\n })\n const projectionRevision = LedgerRevision.make(current.projection.projectionRevision + 1)\n const receipt = yield* writeGraph(persistence, scope.workspaceId, {\n entityProjections: [{\n projection: {\n ...current.projection,\n projectionRevision,\n sourceEntityRevision: LedgerRevision.make(persisted.revision),\n supersedesProjectionRevision: current.projection.projectionRevision,\n entityState: \"deleted\"\n },\n recordedAt: scope.committedAt\n }],\n nodes: [],\n evidenceItems: [],\n evidenceClaims: [],\n relationships: []\n }, event.eventId)\n return { entityProjectionCount: receipt.entityProjectionCount }\n})\n\nconst materializePerson = Effect.fn(\"NormalizedPluginPageMaterialization.upsertPerson\")(function*(\n persistence: PersistenceService,\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n event: PersonUpsert\n) {\n const identity = {\n pluginConnectionId: scope.pluginConnectionId,\n providerId: scope.providerId,\n vendorPersonId: VendorImmutableId.make(event.vendorPersonId)\n }\n const existing = yield* persistence.people.findPersonBySourceIdentity(scope.workspaceId, identity).pipe(\n Effect.result\n )\n if (Result.isFailure(existing) && existing.failure._tag !== \"RecordNotFoundError\") {\n return yield* existing.failure\n }\n const personId = Result.isSuccess(existing)\n ? existing.success.person.personId\n : PersonId.make(\n yield* stableUuid(\n cryptoService,\n materializationKey(scope, \"person\", event.vendorPersonId),\n event.eventId\n )\n )\n const avatar = event.avatarUrl !== null && event.avatarUrl.toString().length <= 500\n ? { _tag: \"reference\", reference: event.avatarUrl.toString() }\n : { _tag: \"initials\", text: derivePersonInitials(event.displayName) }\n const person = yield* Schema.decodeUnknownEffect(Schema.toType(Person))({\n personId,\n displayName: event.displayName,\n avatar,\n isActive: event.active,\n sourceIdentities: Result.isSuccess(existing) ? existing.success.person.sourceIdentities : [identity]\n }).pipe(Effect.mapError(() => malformed(\"normalized-person-invalid\", event.eventId)))\n if (\n Result.isSuccess(existing) &&\n existing.success.person.displayName === person.displayName &&\n existing.success.person.isActive === person.isActive &&\n existing.success.person.avatar._tag === person.avatar._tag &&\n (existing.success.person.avatar._tag === \"initials\"\n ? existing.success.person.avatar.text === (person.avatar._tag === \"initials\" ? person.avatar.text : \"\")\n : existing.success.person.avatar.reference ===\n (person.avatar._tag === \"reference\" ? person.avatar.reference : \"\"))\n ) {\n return 0\n }\n if (Result.isSuccess(existing)) {\n yield* persistence.people.updatePerson(\n scope.workspaceId,\n person,\n existing.success.revision,\n scope.committedAt\n )\n } else {\n yield* persistence.people.createPerson(scope.workspaceId, person, scope.committedAt)\n }\n return 1\n})\n\nconst evidencePredicate = (event: EvidenceAppend): typeof EvidencePredicate.Type => {\n const decoded = Schema.decodeUnknownResult(EvidencePredicate)(event.evidenceType)\n if (Result.isSuccess(decoded)) return decoded.success\n return \"status-observed\"\n}\n\nconst materializeEvidence = Effect.fn(\"NormalizedPluginPageMaterialization.appendEvidence\")(function*(\n persistence: PersistenceService,\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n event: EvidenceAppend\n) {\n const subject = yield* findEntity(persistence, scope, event.subject.vendorImmutableId)\n if (subject === null) return yield* malformed(\"normalized-evidence-subject-missing\", event.eventId)\n const subjectKind = canonicalKind(event.subject.entityType)\n if (subjectKind === null) return yield* malformed(\"normalized-evidence-subject-unsupported\", event.eventId)\n const nodeId = yield* nodeIdFor(cryptoService, scope, event.subject.vendorImmutableId, event.eventId)\n const evidenceId = EvidenceId.make(\n yield* stableUuid(\n cryptoService,\n materializationKey(scope, \"evidence\", event.evidenceId),\n event.eventId\n )\n )\n const evidenceClaimId = EvidenceClaimId.make(\n yield* stableUuid(\n cryptoService,\n materializationKey(scope, \"evidence-claim\", event.evidenceId),\n event.eventId\n )\n )\n const decodedData = Schema.decodeUnknownResult(EvidenceData)(event.data)\n const predicate = Result.isSuccess(decodedData) && decodedData.success.predicate !== undefined\n ? decodedData.success.predicate\n : evidencePredicate(event)\n const value: typeof EvidenceValue.Type = Result.isSuccess(decodedData) && decodedData.success.value !== undefined\n ? decodedData.success.value\n : { _tag: \"state\", value: event.summary }\n const source = subject.sourceRevision\n const ageSeconds = Math.max(\n 0,\n (DateTime.toEpochMillis(scope.committedAt) - DateTime.toEpochMillis(source.lastObservedAt)) / 1_000\n )\n const health: Extract<PluginHealth, { readonly _tag: \"degraded\" | \"healthy\" }> =\n scope.successfulHealth._tag === \"healthy\"\n ? { _tag: \"healthy\", checkedAt: scope.committedAt }\n : { ...scope.successfulHealth, checkedAt: scope.committedAt }\n const receipt = yield* writeGraph(persistence, scope.workspaceId, {\n entityProjections: [],\n nodes: [],\n evidenceItems: [{\n workspaceId: scope.workspaceId,\n evidenceId,\n schemaVersion: 1,\n attribution: {\n _tag: \"plugin\",\n pluginConnectionId: scope.pluginConnectionId,\n sourceEntityId: subject.entityId,\n sourceEntityRevision: LedgerRevision.make(subject.revision)\n },\n verifier: { _tag: \"system\", component: \"normalized-plugin-page-materializer\" },\n observedAt: event.capturedAt,\n recordedAt: scope.committedAt,\n validUntil: null,\n freshness: {\n _tag: \"current\",\n evaluatedAt: scope.committedAt,\n pluginHealth: health,\n provenance: { _tag: \"provider\", sourceRevision: source },\n sourceObservedAt: source.lastObservedAt,\n staleAfterSeconds: Math.max(1, Math.ceil(ageSeconds) + 1),\n synchronizedAt: scope.committedAt\n },\n retention: { classification: \"evidence\", retainUntil: null, legalHold: false }\n }],\n evidenceClaims: [{\n workspaceId: scope.workspaceId,\n evidenceClaimId,\n evidenceId,\n subjectNodeId: nodeId,\n predicate,\n value,\n recordedAt: scope.committedAt,\n supersedesEvidenceClaimId: null\n }],\n relationships: []\n }, event.eventId)\n return {\n evidenceItemCount: receipt.evidenceItemCount,\n evidenceClaimCount: receipt.evidenceClaimCount\n }\n})\n\nconst materializeRelationship = Effect.fn(\n \"NormalizedPluginPageMaterialization.proposeRelationship\"\n)(function*(\n persistence: PersistenceService,\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n event: RelationshipProposal\n) {\n const resolveEndpoint = Effect.fn(\"NormalizedPluginPageMaterialization.resolveRelationshipEndpoint\")(function*(\n reference: RelationshipProposal[\"from\"]\n ) {\n if (reference.entityType === \"release\") {\n const releaseId = yield* releaseIdFor(cryptoService, scope, reference.vendorImmutableId, event.eventId)\n const release = yield* persistence.releases.get(scope.workspaceId, releaseId).pipe(Effect.result)\n if (Result.isFailure(release)) {\n if (release.failure._tag === \"RecordNotFoundError\") {\n return yield* malformed(\"normalized-relationship-endpoint-missing\", event.eventId)\n }\n return yield* release.failure\n }\n const nodeId = yield* releaseNodeIdFor(cryptoService, scope, reference.vendorImmutableId, event.eventId)\n const existingNode = yield* persistence.deliveryGraph.read(scope.workspaceId, {\n _tag: \"node\",\n nodeId\n }).pipe(Effect.result)\n if (Result.isFailure(existingNode) && existingNode.failure._tag !== \"RecordNotFoundError\") {\n return yield* existingNode.failure\n }\n return {\n entity: null,\n kind: \"release\",\n node: Result.isSuccess(existingNode)\n ? null\n : {\n workspaceId: scope.workspaceId,\n nodeId,\n endpointKind: \"release\",\n resolution: { _tag: \"resolved\", target: { _tag: \"release\", releaseId } },\n createdAt: scope.committedAt\n },\n nodeId,\n releaseId\n } satisfies RelationshipEndpointResolution\n }\n const entity = yield* findEntity(persistence, scope, reference.vendorImmutableId)\n const kind = canonicalKind(reference.entityType)\n if (entity === null) return yield* malformed(\"normalized-relationship-endpoint-missing\", event.eventId)\n if (kind === null) return yield* malformed(\"normalized-relationship-endpoint-unsupported\", event.eventId)\n return {\n entity,\n kind,\n node: null,\n nodeId: yield* nodeIdFor(cryptoService, scope, reference.vendorImmutableId, event.eventId),\n releaseId: null\n } satisfies RelationshipEndpointResolution\n })\n const source = yield* resolveEndpoint(event.from)\n const target = yield* resolveEndpoint(event.to)\n const kind = yield* Schema.decodeUnknownEffect(RelationshipKind)(event.relationshipType).pipe(\n Effect.mapError(() => malformed(\"normalized-relationship-kind-invalid\", event.eventId))\n )\n const provenanceEntity = source.entity ?? target.entity\n if (provenanceEntity === null) {\n return yield* malformed(\"normalized-relationship-provenance-entity-missing\", event.eventId)\n }\n const relationshipScope: DeliveryRelationship[\"scope\"] = source.releaseId !== null\n ? { _tag: \"release\", releaseId: source.releaseId }\n : null\n const relationshipId = RelationshipId.make(\n yield* stableUuid(\n cryptoService,\n materializationKey(scope, \"relationship\", event.relationshipId),\n event.eventId\n )\n )\n const existing = yield* persistence.deliveryGraph.read(scope.workspaceId, {\n _tag: \"relationship\",\n relationshipId,\n revision: null\n }).pipe(Effect.result)\n if (Result.isFailure(existing) && existing.failure._tag !== \"RecordNotFoundError\") {\n return yield* existing.failure\n }\n const previous = Result.isSuccess(existing) && existing.success._tag === \"relationship\"\n ? existing.success.value\n : null\n const revision = LedgerRevision.make((previous?.revision ?? 0) + 1)\n const nodes: Array<DeliveryNode> = []\n if (source.node !== null) nodes.push(source.node)\n if (target.node !== null && target.node.nodeId !== source.nodeId) nodes.push(target.node)\n const receipt = yield* writeGraph(\n persistence,\n scope.workspaceId,\n {\n entityProjections: [],\n nodes,\n evidenceItems: [],\n evidenceClaims: [],\n relationships: [\n {\n workspaceId: scope.workspaceId,\n relationshipId,\n relationshipSchemaVersion: 1,\n revision,\n supersedesRevision: previous?.revision ?? null,\n kind,\n sourceNodeId: source.nodeId,\n sourceNodeKind: source.kind,\n targetNodeId: target.nodeId,\n targetNodeKind: target.kind,\n scope: relationshipScope,\n lifecycle: { _tag: \"proposed\", effectiveAt: event.observedAt },\n confidence: {\n _tag: \"inferred\",\n score: event.confidence,\n rationale: `Proposed by ${scope.providerId} normalized synchronization.`\n },\n provenance: {\n _tag: \"plugin\",\n pluginConnectionId: scope.pluginConnectionId,\n sourceEntityId: provenanceEntity.entityId,\n sourceEntityRevision: LedgerRevision.make(provenanceEntity.revision)\n },\n recordedBy: { _tag: \"system\", component: \"normalized-plugin-page-materializer\" },\n evidenceClaimIds: yield* Effect.forEach(\n event.evidenceIds,\n (evidenceId) =>\n stableUuid(cryptoService, materializationKey(scope, \"evidence-claim\", evidenceId), event.eventId).pipe(\n Effect.map(EvidenceClaimId.make)\n )\n ),\n recordedAt: scope.committedAt\n }\n ]\n },\n event.eventId\n )\n return { nodeCount: receipt.nodeCount, relationshipCount: receipt.relationshipCount }\n})\n\nconst hasAuthoritativeJiraFixVersions = (event: NormalizedPluginEventV1): event is EntityUpsert => {\n if (event._tag !== \"UpsertEntity\" || event.entityType !== \"jira.issue\") return false\n const snapshot = Schema.decodeUnknownResult(JiraIssueRelationshipSnapshot)(event.attributes)\n return Result.isSuccess(snapshot) && !snapshot.success.truncatedFields.includes(\"fixVersions\")\n}\n\nconst isReleaseContainmentForIssue = (\n event: NormalizedPluginEventV1,\n issue: EntityUpsert\n): event is RelationshipProposal =>\n event._tag === \"ProposeRelationship\" &&\n event.relationshipType === \"contains\" &&\n event.from.entityType === \"release\" &&\n event.to.entityType === issue.entityType &&\n event.to.vendorImmutableId === issue.vendorImmutableId\n\nconst retireMissingJiraReleaseContainments = Effect.fn(\n \"NormalizedPluginPageMaterialization.retireMissingJiraReleaseContainments\"\n)(function*(\n persistence: PersistenceService,\n cryptoService: Crypto.Crypto,\n scope: NormalizedPluginPageMaterializationScope,\n acceptedEvents: ReadonlyArray<NormalizedPluginEventV1>\n) {\n let relationshipCount = 0\n for (const issue of acceptedEvents) {\n if (!hasAuthoritativeJiraFixVersions(issue)) continue\n const source = yield* findEntity(persistence, scope, issue.vendorImmutableId)\n if (source === null) return yield* malformed(\"normalized-relationship-endpoint-missing\", issue.eventId)\n const issueNodeId = yield* nodeIdFor(cryptoService, scope, issue.vendorImmutableId, issue.eventId)\n const neighborhood = yield* persistence.deliveryGraph.read(scope.workspaceId, {\n _tag: \"nodeRelationships\",\n nodeId: issueNodeId,\n limit: 500\n })\n if (neighborhood._tag !== \"nodeRelationships\") continue\n if (neighborhood.value.truncated) {\n return yield* malformed(\"normalized-jira-containment-neighborhood-truncated\", issue.eventId)\n }\n const currentRelationshipIds = new Set(\n yield* Effect.forEach(\n acceptedEvents.filter((event) => isReleaseContainmentForIssue(event, issue)),\n ({ relationshipId }) =>\n stableUuid(\n cryptoService,\n materializationKey(scope, \"relationship\", relationshipId),\n issue.eventId\n ).pipe(Effect.map(RelationshipId.make))\n )\n )\n const removed = neighborhood.value.relationships.filter(\n (relationship) =>\n relationship.kind === \"contains\" &&\n relationship.sourceNodeKind === \"release\" &&\n relationship.targetNodeId === issueNodeId &&\n relationship.targetNodeKind === \"issue\" &&\n relationship.provenance._tag === \"plugin\" &&\n relationship.provenance.pluginConnectionId === scope.pluginConnectionId &&\n relationship.provenance.sourceEntityId === source.entityId &&\n !currentRelationshipIds.has(relationship.relationshipId)\n )\n if (removed.length === 0) continue\n\n for (const previous of removed) {\n if (previous.lifecycle._tag === \"rejected\" || previous.lifecycle._tag === \"superseded\") continue\n const receipt = yield* writeGraph(persistence, scope.workspaceId, {\n entityProjections: [],\n nodes: [],\n evidenceItems: [],\n evidenceClaims: [],\n relationships: [{\n ...previous,\n revision: LedgerRevision.make(previous.revision + 1),\n supersedesRevision: previous.revision,\n lifecycle: {\n _tag: \"superseded\",\n effectiveAt: issue.observedAt,\n reason: \"No longer present in the latest Jira fixVersion observation.\"\n },\n provenance: {\n _tag: \"plugin\",\n pluginConnectionId: scope.pluginConnectionId,\n sourceEntityId: source.entityId,\n sourceEntityRevision: LedgerRevision.make(source.revision)\n },\n recordedBy: { _tag: \"system\", component: \"normalized-plugin-page-materializer\" },\n recordedAt: scope.committedAt\n }]\n }, issue.eventId)\n relationshipCount += receipt.relationshipCount\n }\n }\n return relationshipCount\n})\n\n/** Host authority supplied separately from provider-controlled normalized data. */\nexport interface NormalizedPluginPageMaterializationScope {\n readonly workspaceId: WorkspaceId\n readonly pluginConnectionId: PluginConnectionId\n readonly providerId: ProviderId\n readonly streamKey: PluginStreamKey\n readonly expectedRevision: number\n readonly committedAt: UtcTimestamp\n readonly successfulHealth: Extract<PluginHealth, { readonly _tag: \"healthy\" | \"degraded\" }>\n readonly expectedAuthority?: PluginSynchronizationAuthority\n}\n\n/** Durable counts from one new page, or zero counts when the exact page is replayed. */\nexport interface NormalizedPluginPageMaterializationReceipt {\n readonly pageCommitted: boolean\n readonly acceptedEventCount: number\n readonly entityProjectionCount: number\n readonly evidenceClaimCount: number\n readonly evidenceItemCount: number\n readonly nodeCount: number\n readonly personCount: number\n readonly relationshipCount: number\n readonly skippedEntityCount: number\n}\n\n/**\n * Commit one decoded page and all accepted canonical projections atomically.\n * The existing plugin checkpoint transaction nests as a savepoint; only its\n * newly accepted event identities cross the materialization seam.\n */\nexport const materializeNormalizedPluginPage = Effect.fn(\n \"NormalizedPluginPageMaterialization.materializePage\"\n)(function*(\n scope: NormalizedPluginPageMaterializationScope,\n page: PluginSyncPageV1\n): Effect.fn.Return<\n NormalizedPluginPageMaterializationReceipt,\n NormalizedPluginPageMaterializationError | PersistenceOperationFailure | PluginConflictFailure,\n Crypto.Crypto | Persistence\n> {\n const cryptoService = yield* Crypto.Crypto\n const persistence = yield* Persistence\n return yield* persistence.transact(Effect.gen(function*() {\n if (scope.expectedAuthority !== undefined) {\n yield* verifyPluginSynchronizationAuthority(persistence, scope.expectedAuthority)\n }\n const committed = yield* persistence.pluginRuntime.commitNormalizedPageReceipt(\n scope.workspaceId,\n scope.pluginConnectionId,\n scope.providerId,\n scope.streamKey,\n scope.expectedRevision,\n page,\n scope.committedAt,\n scope.successfulHealth\n )\n const accepted = new Set(committed.acceptedEventIds)\n const events = page.events.filter(({ eventId }) => accepted.has(eventId))\n let entityProjectionCount = 0\n let evidenceClaimCount = 0\n let evidenceItemCount = 0\n let nodeCount = 0\n let personCount = 0\n let relationshipCount = 0\n let skippedEntityCount = 0\n\n for (const event of events) {\n if (event._tag !== \"UpsertPerson\") continue\n personCount += yield* materializePerson(persistence, cryptoService, scope, event)\n }\n for (const event of events) {\n if (event._tag === \"UpsertEntity\") {\n if (event.entityType === \"release\") {\n nodeCount += (yield* materializeRelease(persistence, cryptoService, scope, event)).nodeCount\n continue\n }\n const receipt = yield* materializeUpsertEntity(persistence, cryptoService, scope, event)\n entityProjectionCount += receipt.entityProjectionCount\n nodeCount += receipt.nodeCount\n skippedEntityCount += receipt.skippedEntityCount\n } else if (event._tag === \"TombstoneEntity\") {\n entityProjectionCount += (yield* materializeTombstoneEntity(persistence, scope, event)).entityProjectionCount\n }\n }\n for (const event of events) {\n if (event._tag !== \"AppendEvidence\") continue\n const receipt = yield* materializeEvidence(persistence, cryptoService, scope, event)\n evidenceItemCount += receipt.evidenceItemCount\n evidenceClaimCount += receipt.evidenceClaimCount\n }\n for (const event of events) {\n if (event._tag !== \"ProposeRelationship\") continue\n const receipt = yield* materializeRelationship(persistence, cryptoService, scope, event)\n nodeCount += receipt.nodeCount\n relationshipCount += receipt.relationshipCount\n }\n relationshipCount += yield* retireMissingJiraReleaseContainments(\n persistence,\n cryptoService,\n scope,\n events\n )\n if (events.length > 0) {\n const inference = yield* materializeRelationshipInference(\n persistence,\n (identity) => stableUuid(cryptoService, identity, \"relationship-inference\"),\n scope\n )\n evidenceClaimCount += inference.evidenceClaimCount\n evidenceItemCount += inference.evidenceItemCount\n nodeCount += inference.nodeCount\n relationshipCount += inference.relationshipCount\n }\n return {\n pageCommitted: committed.pageCommitted,\n acceptedEventCount: events.length,\n entityProjectionCount,\n evidenceClaimCount,\n evidenceItemCount,\n nodeCount,\n personCount,\n relationshipCount,\n skippedEntityCount\n }\n }))\n})\n","import * as Clock from \"effect/Clock\"\nimport * as Context from \"effect/Context\"\nimport * as Crypto from \"effect/Crypto\"\nimport * as DateTime from \"effect/DateTime\"\nimport * as Effect from \"effect/Effect\"\nimport * as Option from \"effect/Option\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport * as Stream from \"effect/Stream\"\n\nimport type { PluginSynchronizationState } from \"../../api/plugins.js\"\nimport { PluginHealth, type PluginHealth as PluginHealthType } from \"../../domain/freshness.js\"\nimport type { PluginConnectionId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport { NegotiatedPluginDescriptorV1 } from \"../../domain/plugins/descriptor.js\"\nimport { PluginCheckpointV1, type PluginSyncPageV1, PluginSyncRequestV1 } from \"../../domain/plugins/events.js\"\nimport type { ProviderId } from \"../../domain/sourceRevision.js\"\nimport type { UtcTimestamp } from \"../../domain/utcTimestamp.js\"\nimport {\n ApplicationInvalidRequest,\n ApplicationResourceNotFound,\n ApplicationServiceUnavailable,\n type PluginAdministrationError\n} from \"../api/ApplicationServices.js\"\nimport type { PersistenceOperationFailure } from \"../persistence/Persistence.js\"\nimport { Persistence } from \"../persistence/Persistence.js\"\nimport type {\n PluginSyncAttemptRecord,\n PluginSyncAttemptState\n} from \"../persistence/repositories/pluginRuntimeModels.js\"\nimport { PluginStreamKey } from \"../persistence/repositories/pluginRuntimeModels.js\"\nimport type { PluginFailure } from \"../plugins/failures.js\"\nimport { pluginFailureClass, PluginMalformedResponseFailure } from \"../plugins/failures.js\"\nimport { firstPartySyncStreamKey, supportsFirstPartySynchronization } from \"../plugins/firstPartySynchronization.js\"\nimport { PluginConnection, type PluginConnectionV1 } from \"../plugins/PluginConnection.js\"\nimport type { PluginConnectionMapV1 } from \"../plugins/PluginConnectionMap.js\"\nimport { DomainEventWakeups } from \"../runtime/DomainEventWakeups.js\"\nimport { materializeNormalizedPluginPage } from \"./normalizedPluginPageMaterialization.js\"\nimport {\n capturePluginSynchronizationAuthority,\n type PluginSynchronizationAuthority,\n verifyPluginSynchronizationAuthority\n} from \"./pluginSynchronizationAuthority.js\"\nimport { appendPortfolioInvalidation } from \"./portfolioInvalidation.js\"\n\nconst MAXIMUM_PAGES_PER_INVOCATION = 100\nconst SYNCHRONIZATION_CLAIM_LIFETIME_MINUTES = 15\nconst SOURCE_UNAVAILABLE_OUTCOME = \"source-unavailable\"\nconst SYNCHRONIZED_OUTCOME = \"synchronized\"\ntype SuccessfulPluginHealth = Extract<PluginHealthType, { readonly _tag: \"healthy\" | \"degraded\" }>\n\nconst successfulHealthAt = (\n health: SuccessfulPluginHealth,\n checkedAt: UtcTimestamp\n): SuccessfulPluginHealth =>\n health._tag === \"healthy\"\n ? { _tag: \"healthy\", checkedAt }\n : {\n ...health,\n checkedAt,\n retryAt: health.retryAt !== null && DateTime.Order(checkedAt, health.retryAt) <= 0\n ? health.retryAt\n : null\n }\n\n/** One provider-neutral manual synchronization driver with a fixed logical stream identity. */\nexport interface ManualPluginSyncDriver {\n readonly providerId: ProviderId\n readonly streamKey: string\n readonly sync: (\n connection: PluginConnectionV1,\n request: typeof PluginSyncRequestV1.Type\n ) => Stream.Stream<PluginSyncPageV1, PluginFailure>\n}\n\n/** Fixed lookup boundary that keeps provider identifiers out of the orchestration state machine. */\nexport interface ManualPluginSyncDriverRegistry {\n readonly get: (providerId: ProviderId) => Option.Option<ManualPluginSyncDriver>\n}\n\n/** Build a deterministic driver registry for production or fixture connections. */\nexport const makeManualPluginSyncDriverRegistry = (\n drivers: ReadonlyArray<ManualPluginSyncDriver>\n): ManualPluginSyncDriverRegistry => {\n const byProvider = new Map<ProviderId, ManualPluginSyncDriver>()\n for (const driver of drivers) byProvider.set(driver.providerId, driver)\n return { get: (providerId) => Option.fromNullishOr(byProvider.get(providerId)) }\n}\n\nconst connectionSync = (\n connection: PluginConnectionV1,\n request: typeof PluginSyncRequestV1.Type\n) => connection.sync(request)\n\n/** Production drivers for first-party connections that currently negotiate synchronization. */\nexport const firstPartyManualPluginSyncDrivers = makeManualPluginSyncDriverRegistry([\n { providerId: \"codecommit\", streamKey: firstPartySyncStreamKey(\"codecommit\"), sync: connectionSync },\n { providerId: \"codepipeline\", streamKey: firstPartySyncStreamKey(\"codepipeline\"), sync: connectionSync },\n { providerId: \"jira\", streamKey: firstPartySyncStreamKey(\"jira\"), sync: connectionSync },\n { providerId: \"clockify\", streamKey: firstPartySyncStreamKey(\"clockify\"), sync: connectionSync },\n { providerId: \"confluence\", streamKey: firstPartySyncStreamKey(\"confluence\"), sync: connectionSync }\n])\n\nconst unavailable = () => new ApplicationServiceUnavailable({ retryAt: null })\n\nconst mapPersistenceRead = (\n failure: PersistenceOperationFailure\n): ApplicationResourceNotFound | ApplicationServiceUnavailable =>\n failure._tag === \"RecordNotFoundError\" ? new ApplicationResourceNotFound() : unavailable()\n\nconst pluginFailureTags = new Set([\n \"PluginAuthenticationFailure\",\n \"PluginAuthorizationFailure\",\n \"PluginRateLimitFailure\",\n \"PluginTimeoutFailure\",\n \"PluginMalformedResponseFailure\",\n \"PluginOutageFailure\",\n \"PluginCancellationFailure\",\n \"PluginConflictFailure\",\n \"PluginUnsupportedCapabilityFailure\",\n \"PluginConfigurationFailure\",\n \"PluginUnknownOutcomeFailure\"\n])\n\nconst isPluginFailure = (failure: unknown): failure is PluginFailure =>\n Predicate.hasProperty(failure, \"_tag\") &&\n typeof failure._tag === \"string\" &&\n pluginFailureTags.has(failure._tag)\n\nconst sourceFailure = (failure: unknown): PluginFailure | null => {\n if (isPluginFailure(failure)) return failure\n if (\n Predicate.hasProperty(failure, \"_tag\") &&\n failure._tag === \"NormalizedPluginPageMaterializationError\"\n ) {\n return new PluginMalformedResponseFailure({\n operation: \"manual-sync\",\n diagnosticCode: \"normalized-plugin-page-rejected\"\n })\n }\n if (\n Predicate.hasProperty(failure, \"_tag\") &&\n failure._tag === \"SourceIdentityMismatchError\" &&\n Predicate.hasProperty(failure, \"recordKind\") &&\n (failure.recordKind === \"plugin-sync-event\" || failure.recordKind === \"plugin-sync-page\")\n ) {\n return new PluginMalformedResponseFailure({\n operation: \"manual-sync\",\n diagnosticCode: \"plugin-sync-source-identity-conflict\"\n })\n }\n return null\n}\n\nconst safeFailureMessage = (failure: PluginFailure): string => {\n switch (failure._tag) {\n case \"PluginAuthenticationFailure\":\n return \"Provider authentication failed.\"\n case \"PluginAuthorizationFailure\":\n return \"Provider permission was denied.\"\n case \"PluginRateLimitFailure\":\n return \"Provider rate limit was reached.\"\n case \"PluginTimeoutFailure\":\n return \"Provider request timed out.\"\n case \"PluginMalformedResponseFailure\":\n return \"Provider returned an invalid response.\"\n case \"PluginOutageFailure\":\n return \"Provider is temporarily unavailable.\"\n case \"PluginCancellationFailure\":\n return \"Provider synchronization was cancelled.\"\n case \"PluginConflictFailure\":\n return \"Provider state changed during synchronization.\"\n case \"PluginUnsupportedCapabilityFailure\":\n return \"Provider synchronization is not supported.\"\n case \"PluginConfigurationFailure\":\n return \"Provider configuration is incomplete.\"\n case \"PluginUnknownOutcomeFailure\":\n return \"Provider synchronization outcome is unknown.\"\n }\n}\n\nconst failureHealth = Effect.fn(\"ManualPluginSynchronization.failureHealth\")(function*(\n failure: PluginFailure,\n checkedAt: UtcTimestamp\n) {\n return yield* Schema.decodeUnknownEffect(Schema.toType(PluginHealth))({\n _tag: \"unavailable\",\n checkedAt,\n failureClass: pluginFailureClass(failure),\n retryAt: failure._tag === \"PluginRateLimitFailure\" ? failure.retryAt : null,\n safeMessage: safeFailureMessage(failure)\n })\n})\n\nconst stateFromAttemptState = (\n pluginConnectionId: PluginConnectionId,\n providerId: ProviderId,\n streamKey: string,\n attemptState: PluginSyncAttemptState\n): PluginSynchronizationState => {\n const lastAttempt: PluginSyncAttemptRecord | undefined = attemptState.latestAttempt ?? undefined\n const lastSuccess: PluginSyncAttemptRecord | undefined = attemptState.latestSynchronized ?? undefined\n return {\n pluginConnectionId,\n providerId,\n streamKey,\n lastAttemptAt: lastAttempt?.startedAt ?? null,\n lastSuccessAt: lastSuccess?.completedAt ?? null,\n result: lastAttempt === undefined\n ? \"never\"\n : lastAttempt.outcome === null\n ? \"running\"\n : lastAttempt.outcome,\n pagesCommitted: lastAttempt?.pagesCommitted ?? 0\n }\n}\n\ninterface BoundManualSync {\n readonly workspaceId: WorkspaceId\n readonly pluginConnectionId: PluginConnectionId\n readonly providerId: ProviderId\n readonly driver: ManualPluginSyncDriver\n readonly streamKey: PluginStreamKey\n}\n\ninterface SynchronizationClaim extends BoundManualSync {\n readonly claimId: string\n}\n\nexport interface ManualPluginSynchronizationService {\n readonly state: (input: {\n readonly workspaceId: WorkspaceId\n readonly pluginConnectionId: PluginConnectionId\n }) => Effect.Effect<PluginSynchronizationState, ApplicationInvalidRequest | PluginAdministrationError>\n readonly synchronize: (input: {\n readonly workspaceId: WorkspaceId\n readonly pluginConnectionId: PluginConnectionId\n }) => Effect.Effect<PluginSynchronizationState, ApplicationInvalidRequest | PluginAdministrationError>\n}\n\n/** Build the bounded synchronization application over a scoped provider runtime map. */\nexport const makeManualPluginSynchronization = Effect.fn(\n \"ManualPluginSynchronization.make\"\n)(function*(\n connections: PluginConnectionMapV1,\n drivers: ManualPluginSyncDriverRegistry = firstPartyManualPluginSyncDrivers\n): Effect.fn.Return<ManualPluginSynchronizationService, never, Crypto.Crypto | DomainEventWakeups | Persistence> {\n const persistence = yield* Persistence\n const wakeups = yield* DomainEventWakeups\n const cryptoService = yield* Crypto.Crypto\n\n const bind = Effect.fn(\"ManualPluginSynchronization.bind\")(function*(input: {\n readonly workspaceId: WorkspaceId\n readonly pluginConnectionId: PluginConnectionId\n }): Effect.fn.Return<BoundManualSync, ApplicationInvalidRequest | PluginAdministrationError> {\n const connection = yield* persistence.pluginConnections.get(\n input.workspaceId,\n input.pluginConnectionId\n ).pipe(Effect.mapError(mapPersistenceRead))\n const driver = drivers.get(connection.providerId)\n if (Option.isNone(driver)) return yield* new ApplicationInvalidRequest()\n const runtime = yield* persistence.pluginRuntime.getRuntime(\n input.workspaceId,\n input.pluginConnectionId\n ).pipe(Effect.mapError(mapPersistenceRead))\n const descriptor = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(NegotiatedPluginDescriptorV1))(\n runtime.descriptorJson\n ).pipe(Effect.mapError(() => new ApplicationInvalidRequest()))\n if (!supportsFirstPartySynchronization(connection.providerId, descriptor)) {\n return yield* new ApplicationInvalidRequest()\n }\n const streamKey = yield* Schema.decodeUnknownEffect(PluginStreamKey)(driver.value.streamKey).pipe(\n Effect.mapError(() => new ApplicationInvalidRequest())\n )\n return { ...input, providerId: connection.providerId, driver: driver.value, streamKey }\n })\n\n const releaseSynchronization = Effect.fn(\n \"ManualPluginSynchronization.releaseSynchronization\"\n )(function*(claim: SynchronizationClaim) {\n yield* persistence.pluginRuntime.releaseSyncClaim(\n claim.workspaceId,\n claim.pluginConnectionId,\n claim.streamKey,\n claim.claimId\n ).pipe(Effect.mapError(() => unavailable()))\n })\n\n const claimSynchronization = Effect.fn(\n \"ManualPluginSynchronization.claimSynchronization\"\n )(function*(bound: BoundManualSync) {\n const claimId = yield* cryptoService.randomUUIDv4.pipe(Effect.mapError(() => unavailable()))\n const claimedAt = DateTime.makeUnsafe(yield* Effect.clockWith((clock) => clock.currentTimeMillis))\n const expiresAt = DateTime.add(claimedAt, { minutes: SYNCHRONIZATION_CLAIM_LIFETIME_MINUTES })\n const claimed = yield* persistence.pluginRuntime.claimSync(\n bound.workspaceId,\n bound.pluginConnectionId,\n bound.providerId,\n bound.streamKey,\n claimId,\n claimedAt,\n expiresAt\n ).pipe(Effect.mapError(() => unavailable()))\n if (!claimed) return yield* unavailable()\n return { ...bound, claimId }\n })\n\n const stateFor = Effect.fn(\"ManualPluginSynchronization.stateFor\")(function*(bound: BoundManualSync) {\n const attemptState = yield* persistence.pluginRuntime.getSyncAttemptState(\n bound.workspaceId,\n bound.pluginConnectionId,\n bound.streamKey\n ).pipe(Effect.mapError(() => unavailable()))\n return stateFromAttemptState(\n bound.pluginConnectionId,\n bound.providerId,\n bound.streamKey,\n attemptState\n )\n })\n\n const readState = Effect.fn(\"ManualPluginSynchronization.state\")(function*(input: {\n readonly workspaceId: WorkspaceId\n readonly pluginConnectionId: PluginConnectionId\n }) {\n const bound = yield* bind(input)\n return yield* stateFor(bound)\n })\n\n const persistHealth = Effect.fn(\"ManualPluginSynchronization.persistHealth\")(function*(\n bound: BoundManualSync,\n authority: PluginSynchronizationAuthority,\n health: PluginHealthType,\n failed: boolean\n ) {\n const persisted = yield* persistence.transact(Effect.gen(function*() {\n yield* verifyPluginSynchronizationAuthority(persistence, authority)\n const runtime = yield* persistence.pluginRuntime.getRuntime(\n bound.workspaceId,\n bound.pluginConnectionId\n )\n yield* persistence.pluginRuntime.recordHealth(\n bound.workspaceId,\n bound.pluginConnectionId,\n runtime.revision,\n health,\n failed ? runtime.consecutiveFailures + 1 : 0\n )\n yield* appendPortfolioInvalidation({\n workspaceId: bound.workspaceId,\n pluginConnectionId: bound.pluginConnectionId,\n releaseId: null,\n occurredAt: health.checkedAt,\n reason: \"plugin-health\"\n }).pipe(\n Effect.provideService(Crypto.Crypto, cryptoService),\n Effect.provideService(Persistence, persistence)\n )\n return true\n })).pipe(\n Effect.catchTag(\"PluginConflictFailure\", () => Effect.succeed(false)),\n Effect.mapError(() => unavailable())\n )\n if (persisted) yield* wakeups.notify(bound.workspaceId)\n return persisted\n })\n\n const initialCheckpoint = Effect.fn(\"ManualPluginSynchronization.initialCheckpoint\")(function*(\n bound: BoundManualSync\n ) {\n const current = yield* Effect.result(\n persistence.pluginRuntime.getStream(bound.workspaceId, bound.pluginConnectionId, bound.streamKey)\n )\n if (Result.isFailure(current)) {\n if (current.failure._tag === \"RecordNotFoundError\") return null\n return yield* Effect.fail(current.failure)\n }\n return current.success.checkpointJson === null\n ? null\n : yield* Schema.decodeUnknownEffect(Schema.fromJsonString(PluginCheckpointV1))(\n current.success.checkpointJson\n )\n })\n\n const run = Effect.fn(\"ManualPluginSynchronization.run\")(function*(\n bound: BoundManualSync,\n authority: PluginSynchronizationAuthority,\n connection: PluginConnectionV1,\n health: SuccessfulPluginHealth\n ) {\n const checkpoint = yield* initialCheckpoint(bound)\n const request = yield* Schema.decodeUnknownEffect(PluginSyncRequestV1)({\n streamKey: bound.streamKey,\n checkpoint\n })\n const initialStream = yield* Effect.result(\n persistence.pluginRuntime.getStream(bound.workspaceId, bound.pluginConnectionId, bound.streamKey)\n )\n const revision = Result.isSuccess(initialStream) ? initialStream.success.revision : 0\n return yield* Stream.runFoldEffect(\n bound.driver.sync(connection, request).pipe(Stream.take(MAXIMUM_PAGES_PER_INVOCATION)),\n () => ({ health, isTerminal: false, pagesSeen: 0, pagesCommitted: 0, revision }),\n (state, page) =>\n Effect.gen(function*() {\n if (state.isTerminal) {\n return yield* new PluginMalformedResponseFailure({\n operation: \"manual-sync\",\n diagnosticCode: \"manual-sync-page-after-terminal\"\n })\n }\n const committedAt = DateTime.makeUnsafe(yield* Clock.currentTimeMillis)\n const successfulHealth = successfulHealthAt(state.health, committedAt)\n const receipt = yield* materializeNormalizedPluginPage({\n workspaceId: bound.workspaceId,\n pluginConnectionId: bound.pluginConnectionId,\n providerId: bound.providerId,\n streamKey: bound.streamKey,\n expectedRevision: state.revision,\n committedAt,\n successfulHealth,\n expectedAuthority: authority\n }, page).pipe(\n Effect.provideService(Crypto.Crypto, cryptoService),\n Effect.provideService(Persistence, persistence)\n )\n const pagesSeen = state.pagesSeen + 1\n return {\n health: successfulHealth,\n isTerminal: !page.hasMore,\n pagesSeen,\n pagesCommitted: state.pagesCommitted + (receipt.pageCommitted ? 1 : 0),\n revision: state.revision + (receipt.pageCommitted ? 1 : 0)\n }\n })\n )\n })\n\n const synchronizeBound = Effect.fn(\"ManualPluginSynchronization.synchronizeBound\")(function*(\n input: {\n readonly workspaceId: WorkspaceId\n readonly pluginConnectionId: PluginConnectionId\n },\n bound: BoundManualSync\n ) {\n const captured = yield* capturePluginSynchronizationAuthority(\n persistence,\n bound.workspaceId,\n bound.pluginConnectionId\n ).pipe(Effect.mapError(mapPersistenceRead))\n const { authority, connection: connectionRecord } = captured\n if (!connectionRecord.isEnabled) return yield* new ApplicationInvalidRequest()\n const startedAt = DateTime.makeUnsafe(yield* Effect.clockWith((clock) => clock.currentTimeMillis))\n const attempt = yield* persistence.pluginRuntime.beginSyncAttempt(\n bound.workspaceId,\n bound.pluginConnectionId,\n bound.providerId,\n bound.streamKey,\n startedAt\n ).pipe(Effect.mapError(() => unavailable()))\n const synchronized = yield* Effect.result(Effect.scoped(\n Effect.flatMap(\n connections.contextEffect({\n workspaceId: bound.workspaceId,\n pluginConnectionId: bound.pluginConnectionId\n }),\n (context) =>\n Effect.gen(function*() {\n const connection = Context.get(context, PluginConnection)\n const health = yield* connection.health\n if (health._tag === \"unavailable\" || health._tag === \"disabled\") return health\n const completed = yield* run(bound, authority, connection, health)\n if (\n !completed.isTerminal &&\n (\n completed.pagesSeen < MAXIMUM_PAGES_PER_INVOCATION ||\n completed.pagesCommitted === 0\n )\n ) {\n return yield* new PluginMalformedResponseFailure({\n operation: \"manual-sync\",\n diagnosticCode: \"manual-sync-terminal-page-missing\"\n })\n }\n return completed.health\n }).pipe(Effect.provide(context))\n )\n ))\n const outcome = yield* Effect.gen(function*() {\n if (Result.isSuccess(synchronized)) {\n const health = synchronized.success\n const sourceUnavailable = health._tag === \"unavailable\" || health._tag === \"disabled\"\n const healthPersisted = yield* persistHealth(bound, authority, health, sourceUnavailable)\n return sourceUnavailable || !healthPersisted ? SOURCE_UNAVAILABLE_OUTCOME : SYNCHRONIZED_OUTCOME\n }\n const failure = sourceFailure(synchronized.failure)\n if (failure === null) return yield* unavailable()\n const failedAt = DateTime.makeUnsafe(yield* Effect.clockWith((clock) => clock.currentTimeMillis))\n const health = yield* failureHealth(failure, failedAt).pipe(Effect.mapError(() => unavailable()))\n yield* persistHealth(bound, authority, health, true)\n return SOURCE_UNAVAILABLE_OUTCOME\n })\n const completedAt = DateTime.makeUnsafe(yield* Effect.clockWith((clock) => clock.currentTimeMillis))\n yield* persistence.pluginRuntime.completeSyncAttempt(\n bound.workspaceId,\n bound.pluginConnectionId,\n bound.streamKey,\n attempt.attemptSequence,\n outcome,\n completedAt\n ).pipe(Effect.mapError(() => unavailable()))\n return yield* readState(input)\n })\n\n const synchronize = Effect.fn(\"ManualPluginSynchronization.synchronize\")(function*(input: {\n readonly workspaceId: WorkspaceId\n readonly pluginConnectionId: PluginConnectionId\n }) {\n const bound = yield* bind(input)\n return yield* Effect.acquireUseRelease(\n claimSynchronization(bound),\n () => synchronizeBound(input, bound),\n releaseSynchronization\n )\n })\n\n return { state: readState, synchronize }\n})\n"],"mappings":"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"}
|