@tiinex/core 0.1.1

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.
Files changed (517) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +31 -0
  3. package/README.md +45 -0
  4. package/package.json +176 -0
  5. package/src/actions/record.actions.js +312 -0
  6. package/src/adapters/adapter.contracts.js +143 -0
  7. package/src/adapters/archive/archive.adapter.js +502 -0
  8. package/src/adapters/archive/archive.portableChangeset.js +141 -0
  9. package/src/adapters/archive/archive.transport.js +124 -0
  10. package/src/artifacts/artifact.localDraft.js +27 -0
  11. package/src/artifacts/artifact.normalize.js +28 -0
  12. package/src/artifacts/artifact.parse.js +207 -0
  13. package/src/artifacts/artifact.record.js +83 -0
  14. package/src/audit/audit.run.js +103 -0
  15. package/src/audit/audit.summary.js +7 -0
  16. package/src/diagnostics/sourceBoundary.report.js +112 -0
  17. package/src/export/package.apply.js +349 -0
  18. package/src/export/package.builder.js +366 -0
  19. package/src/export/package.bytes.js +164 -0
  20. package/src/export/package.controlIntegrity.js +42 -0
  21. package/src/export/package.controlTopology.js +97 -0
  22. package/src/export/package.fileMap.js +174 -0
  23. package/src/export/package.manifest.js +401 -0
  24. package/src/export/package.preflight.js +204 -0
  25. package/src/export/package.sourceReference.js +81 -0
  26. package/src/export/package.workspaceContext.js +144 -0
  27. package/src/export/package.zip.js +128 -0
  28. package/src/export/tree.bundle.js +278 -0
  29. package/src/governance/governance.boundary.js +196 -0
  30. package/src/integrity/integrity.c14nV2.js +190 -0
  31. package/src/integrity/integrity.methodReference.js +73 -0
  32. package/src/integrity/integrity.validate.js +56 -0
  33. package/src/lineage/lineage.candidateResolution.js +46 -0
  34. package/src/lineage/lineage.githubIssueComment.js +106 -0
  35. package/src/lineage/lineage.githubIssueLocal.js +196 -0
  36. package/src/lineage/lineage.githubIssueTarget.js +89 -0
  37. package/src/lineage/lineage.integrity.js +133 -0
  38. package/src/lineage/lineage.materialPreference.js +26 -0
  39. package/src/lineage/lineage.model.js +63 -0
  40. package/src/lineage/lineage.parentAuthority.js +5 -0
  41. package/src/lineage/lineage.parentBinding.js +104 -0
  42. package/src/lineage/lineage.pathBasis.js +47 -0
  43. package/src/lineage/lineage.resolve.js +388 -0
  44. package/src/lineage/lineage.sourceScope.js +74 -0
  45. package/src/lineage/lineage.targetKeys.js +80 -0
  46. package/src/lineage/lineage.traverse.js +132 -0
  47. package/src/public/applicationProjection.js +236 -0
  48. package/src/public/companionResources.js +246 -0
  49. package/src/public/index.js +16 -0
  50. package/src/public/node.js +2 -0
  51. package/src/public/schemaAncestry.js +26 -0
  52. package/src/publication/publication.contract.js +196 -0
  53. package/src/publication/publication.preflight.js +159 -0
  54. package/src/publication/publication.targetContract.js +241 -0
  55. package/src/reingest/reingest.plan.js +162 -0
  56. package/src/release/plan.mjs +28 -0
  57. package/src/release/policy.mjs +100 -0
  58. package/src/release/run.mjs +74 -0
  59. package/src/schemas/capability.registry.js +226 -0
  60. package/src/schemas/companion.js +245 -0
  61. package/src/schemas/contracts.js +6 -0
  62. package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.js +14 -0
  63. package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.json +23 -0
  64. package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.runtime.json +4283 -0
  65. package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.source.js +9 -0
  66. package/src/schemas/coordination/project/tiinex.project.v1.schema.js +26 -0
  67. package/src/schemas/coordination/project/tiinex.project.v1.schema.json +23 -0
  68. package/src/schemas/coordination/project/tiinex.project.v1.schema.runtime.json +1985 -0
  69. package/src/schemas/coordination/project/tiinex.project.v1.schema.source.js +9 -0
  70. package/src/schemas/core/decision/tiinex.decision.v1.schema.js +14 -0
  71. package/src/schemas/core/decision/tiinex.decision.v1.schema.json +24 -0
  72. package/src/schemas/core/decision/tiinex.decision.v1.schema.runtime.json +1700 -0
  73. package/src/schemas/core/decision/tiinex.decision.v1.schema.source.js +9 -0
  74. package/src/schemas/core/evidence/tiinex.evidence.v1.capabilities.js +14 -0
  75. package/src/schemas/core/evidence/tiinex.evidence.v1.en.i18n.json +6 -0
  76. package/src/schemas/core/evidence/tiinex.evidence.v1.findings.js +9 -0
  77. package/src/schemas/core/evidence/tiinex.evidence.v1.presenter.js +1 -0
  78. package/src/schemas/core/evidence/tiinex.evidence.v1.schema.js +32 -0
  79. package/src/schemas/core/evidence/tiinex.evidence.v1.schema.json +24 -0
  80. package/src/schemas/core/evidence/tiinex.evidence.v1.schema.runtime.json +2184 -0
  81. package/src/schemas/core/evidence/tiinex.evidence.v1.schema.source.js +9 -0
  82. package/src/schemas/core/evidence/tiinex.evidence.v1.sv.i18n.json +6 -0
  83. package/src/schemas/core/evidence/tiinex.evidence.v1.transitions.js +1 -0
  84. package/src/schemas/core/evidence/tiinex.evidence.v1.validate.js +10 -0
  85. package/src/schemas/core/feedback/tiinex.feedback.v1.schema.js +14 -0
  86. package/src/schemas/core/feedback/tiinex.feedback.v1.schema.json +23 -0
  87. package/src/schemas/core/feedback/tiinex.feedback.v1.schema.runtime.json +1773 -0
  88. package/src/schemas/core/feedback/tiinex.feedback.v1.schema.source.js +9 -0
  89. package/src/schemas/core/interpretation/tiinex.interpretation.v1.capabilities.js +11 -0
  90. package/src/schemas/core/interpretation/tiinex.interpretation.v1.contract.js +40 -0
  91. package/src/schemas/core/interpretation/tiinex.interpretation.v1.en.i18n.json +9 -0
  92. package/src/schemas/core/interpretation/tiinex.interpretation.v1.findings.js +12 -0
  93. package/src/schemas/core/interpretation/tiinex.interpretation.v1.localMaterialization.js +89 -0
  94. package/src/schemas/core/interpretation/tiinex.interpretation.v1.presenter.js +8 -0
  95. package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.js +34 -0
  96. package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.json +23 -0
  97. package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.runtime.json +2029 -0
  98. package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.source.js +9 -0
  99. package/src/schemas/core/interpretation/tiinex.interpretation.v1.sv.i18n.json +9 -0
  100. package/src/schemas/core/interpretation/tiinex.interpretation.v1.transitions.js +1 -0
  101. package/src/schemas/core/interpretation/tiinex.interpretation.v1.validate.js +25 -0
  102. package/src/schemas/core/preservation/tiinex.preservation.v1.capabilities.js +14 -0
  103. package/src/schemas/core/preservation/tiinex.preservation.v1.en.i18n.json +6 -0
  104. package/src/schemas/core/preservation/tiinex.preservation.v1.findings.js +9 -0
  105. package/src/schemas/core/preservation/tiinex.preservation.v1.presenter.js +1 -0
  106. package/src/schemas/core/preservation/tiinex.preservation.v1.schema.js +31 -0
  107. package/src/schemas/core/preservation/tiinex.preservation.v1.schema.json +23 -0
  108. package/src/schemas/core/preservation/tiinex.preservation.v1.schema.runtime.json +2033 -0
  109. package/src/schemas/core/preservation/tiinex.preservation.v1.schema.source.js +9 -0
  110. package/src/schemas/core/preservation/tiinex.preservation.v1.sv.i18n.json +6 -0
  111. package/src/schemas/core/preservation/tiinex.preservation.v1.transitions.js +1 -0
  112. package/src/schemas/core/preservation/tiinex.preservation.v1.validate.js +10 -0
  113. package/src/schemas/core/relation/tiinex.relation.v1.capabilities.js +7 -0
  114. package/src/schemas/core/relation/tiinex.relation.v1.contract.js +3 -0
  115. package/src/schemas/core/relation/tiinex.relation.v1.en.i18n.json +4 -0
  116. package/src/schemas/core/relation/tiinex.relation.v1.findings.js +9 -0
  117. package/src/schemas/core/relation/tiinex.relation.v1.localMaterialization.js +153 -0
  118. package/src/schemas/core/relation/tiinex.relation.v1.presenter.js +3 -0
  119. package/src/schemas/core/relation/tiinex.relation.v1.schema.js +20 -0
  120. package/src/schemas/core/relation/tiinex.relation.v1.schema.json +23 -0
  121. package/src/schemas/core/relation/tiinex.relation.v1.schema.runtime.json +1668 -0
  122. package/src/schemas/core/relation/tiinex.relation.v1.schema.source.js +9 -0
  123. package/src/schemas/core/relation/tiinex.relation.v1.sv.i18n.json +4 -0
  124. package/src/schemas/core/relation/tiinex.relation.v1.transitions.js +1 -0
  125. package/src/schemas/core/relation/tiinex.relation.v1.validate.js +36 -0
  126. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.capabilities.js +14 -0
  127. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.contract.js +57 -0
  128. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.en.i18n.json +4 -0
  129. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.findings.js +13 -0
  130. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.presenter.js +3 -0
  131. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.js +20 -0
  132. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.json +24 -0
  133. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.runtime.json +3315 -0
  134. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.source.js +9 -0
  135. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.sv.i18n.json +4 -0
  136. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.transitions.js +1 -0
  137. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.validate.js +78 -0
  138. package/src/schemas/core/signal/tiinex.signal.v1.schema.js +14 -0
  139. package/src/schemas/core/signal/tiinex.signal.v1.schema.json +23 -0
  140. package/src/schemas/core/signal/tiinex.signal.v1.schema.runtime.json +1733 -0
  141. package/src/schemas/core/signal/tiinex.signal.v1.schema.source.js +9 -0
  142. package/src/schemas/core/task/tiinex.task.v1.capabilities.js +11 -0
  143. package/src/schemas/core/task/tiinex.task.v1.contract.js +3 -0
  144. package/src/schemas/core/task/tiinex.task.v1.en.i18n.json +15 -0
  145. package/src/schemas/core/task/tiinex.task.v1.findings.js +18 -0
  146. package/src/schemas/core/task/tiinex.task.v1.localMaterialization.js +148 -0
  147. package/src/schemas/core/task/tiinex.task.v1.presenter.js +8 -0
  148. package/src/schemas/core/task/tiinex.task.v1.schema.js +35 -0
  149. package/src/schemas/core/task/tiinex.task.v1.schema.json +23 -0
  150. package/src/schemas/core/task/tiinex.task.v1.schema.runtime.json +1708 -0
  151. package/src/schemas/core/task/tiinex.task.v1.schema.source.js +9 -0
  152. package/src/schemas/core/task/tiinex.task.v1.sv.i18n.json +15 -0
  153. package/src/schemas/core/task/tiinex.task.v1.transitions.js +3 -0
  154. package/src/schemas/core/task/tiinex.task.v1.validate.js +41 -0
  155. package/src/schemas/core/topic/tiinex.topic.v1.capabilities.js +14 -0
  156. package/src/schemas/core/topic/tiinex.topic.v1.creation.js +46 -0
  157. package/src/schemas/core/topic/tiinex.topic.v1.en.i18n.json +8 -0
  158. package/src/schemas/core/topic/tiinex.topic.v1.findings.js +11 -0
  159. package/src/schemas/core/topic/tiinex.topic.v1.localMaterialization.js +135 -0
  160. package/src/schemas/core/topic/tiinex.topic.v1.presenter.js +1 -0
  161. package/src/schemas/core/topic/tiinex.topic.v1.schema.js +34 -0
  162. package/src/schemas/core/topic/tiinex.topic.v1.schema.json +23 -0
  163. package/src/schemas/core/topic/tiinex.topic.v1.schema.runtime.json +1699 -0
  164. package/src/schemas/core/topic/tiinex.topic.v1.schema.source.js +9 -0
  165. package/src/schemas/core/topic/tiinex.topic.v1.sv.i18n.json +8 -0
  166. package/src/schemas/core/topic/tiinex.topic.v1.transitions.js +31 -0
  167. package/src/schemas/core/topic/tiinex.topic.v1.validate.js +11 -0
  168. package/src/schemas/creation.capability.js +289 -0
  169. package/src/schemas/creation.contracts.js +334 -0
  170. package/src/schemas/creation.executionSnapshot.js +79 -0
  171. package/src/schemas/creation.factoryQualification.js +73 -0
  172. package/src/schemas/creation.renderer.js +244 -0
  173. package/src/schemas/creation.representation.js +279 -0
  174. package/src/schemas/creation.rootMetadata.js +6 -0
  175. package/src/schemas/creation.schemaReferences.js +65 -0
  176. package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.js +14 -0
  177. package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.json +23 -0
  178. package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.runtime.json +1873 -0
  179. package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.source.js +9 -0
  180. package/src/schemas/discovery/tiinex.discovery.v1.schema.js +14 -0
  181. package/src/schemas/discovery/tiinex.discovery.v1.schema.json +23 -0
  182. package/src/schemas/discovery/tiinex.discovery.v1.schema.runtime.json +1839 -0
  183. package/src/schemas/discovery/tiinex.discovery.v1.schema.source.js +9 -0
  184. package/src/schemas/generic.artifact.module.js +25 -0
  185. package/src/schemas/party/organization/tiinex.party.organization.v1.schema.js +26 -0
  186. package/src/schemas/party/organization/tiinex.party.organization.v1.schema.json +23 -0
  187. package/src/schemas/party/organization/tiinex.party.organization.v1.schema.runtime.json +2249 -0
  188. package/src/schemas/party/organization/tiinex.party.organization.v1.schema.source.js +9 -0
  189. package/src/schemas/party/role/tiinex.party.role.v1.schema.js +26 -0
  190. package/src/schemas/party/role/tiinex.party.role.v1.schema.json +24 -0
  191. package/src/schemas/party/role/tiinex.party.role.v1.schema.runtime.json +2091 -0
  192. package/src/schemas/party/role/tiinex.party.role.v1.schema.source.js +9 -0
  193. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.capabilities.js +14 -0
  194. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.en.i18n.json +4 -0
  195. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.findings.js +1 -0
  196. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.presenter.js +1 -0
  197. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.js +29 -0
  198. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.json +21 -0
  199. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.runtime.json +2180 -0
  200. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.source.js +9 -0
  201. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.sv.i18n.json +4 -0
  202. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.transitions.js +1 -0
  203. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.validate.js +1 -0
  204. package/src/schemas/reduction/tiinex.reduction.v1.schema.js +26 -0
  205. package/src/schemas/reduction/tiinex.reduction.v1.schema.json +23 -0
  206. package/src/schemas/reduction/tiinex.reduction.v1.schema.runtime.json +1733 -0
  207. package/src/schemas/reduction/tiinex.reduction.v1.schema.source.js +9 -0
  208. package/src/schemas/reference.shapes.js +33 -0
  209. package/src/schemas/registry.js +36 -0
  210. package/src/schemas/resolver.js +13 -0
  211. package/src/schemas/schema/module/tiinex.schema.module.v1.capabilities.js +14 -0
  212. package/src/schemas/schema/module/tiinex.schema.module.v1.en.i18n.json +4 -0
  213. package/src/schemas/schema/module/tiinex.schema.module.v1.findings.js +1 -0
  214. package/src/schemas/schema/module/tiinex.schema.module.v1.presenter.js +1 -0
  215. package/src/schemas/schema/module/tiinex.schema.module.v1.schema.js +29 -0
  216. package/src/schemas/schema/module/tiinex.schema.module.v1.schema.json +21 -0
  217. package/src/schemas/schema/module/tiinex.schema.module.v1.schema.runtime.json +2093 -0
  218. package/src/schemas/schema/module/tiinex.schema.module.v1.schema.source.js +9 -0
  219. package/src/schemas/schema/module/tiinex.schema.module.v1.sv.i18n.json +4 -0
  220. package/src/schemas/schema/module/tiinex.schema.module.v1.transitions.js +1 -0
  221. package/src/schemas/schema/module/tiinex.schema.module.v1.validate.js +1 -0
  222. package/src/schemas/schema.factory.descriptor.js +104 -0
  223. package/src/schemas/schema.githubSourceTarget.js +131 -0
  224. package/src/schemas/schema.identity.js +10 -0
  225. package/src/schemas/schema.reference.js +133 -0
  226. package/src/schemas/schema.source.js +239 -0
  227. package/src/schemas/tiinex.root.v1.capabilities.js +14 -0
  228. package/src/schemas/tiinex.root.v1.classify.js +55 -0
  229. package/src/schemas/tiinex.root.v1.en.i18n.json +24 -0
  230. package/src/schemas/tiinex.root.v1.fallback.js +84 -0
  231. package/src/schemas/tiinex.root.v1.findings.js +19 -0
  232. package/src/schemas/tiinex.root.v1.presenter.js +5 -0
  233. package/src/schemas/tiinex.root.v1.schema.js +29 -0
  234. package/src/schemas/tiinex.root.v1.schema.json +24 -0
  235. package/src/schemas/tiinex.root.v1.schema.runtime.json +1574 -0
  236. package/src/schemas/tiinex.root.v1.schema.source.js +9 -0
  237. package/src/schemas/tiinex.root.v1.sv.i18n.json +24 -0
  238. package/src/schemas/tiinex.root.v1.transitions.js +1 -0
  239. package/src/schemas/tiinex.root.v1.validate.js +36 -0
  240. package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.js +14 -0
  241. package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.json +23 -0
  242. package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.runtime.json +2027 -0
  243. package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.source.js +9 -0
  244. package/src/schemas/validation/method/tiinex.validation.method.v1.schema.js +14 -0
  245. package/src/schemas/validation/method/tiinex.validation.method.v1.schema.json +23 -0
  246. package/src/schemas/validation/method/tiinex.validation.method.v1.schema.runtime.json +1848 -0
  247. package/src/schemas/validation/method/tiinex.validation.method.v1.schema.source.js +9 -0
  248. package/src/schemas/validation/report/tiinex.validation.report.v1.schema.js +14 -0
  249. package/src/schemas/validation/report/tiinex.validation.report.v1.schema.json +23 -0
  250. package/src/schemas/validation/report/tiinex.validation.report.v1.schema.runtime.json +2015 -0
  251. package/src/schemas/validation/report/tiinex.validation.report.v1.schema.source.js +9 -0
  252. package/src/schemas/workspace/tiinex.workspace.v1.capabilities.js +12 -0
  253. package/src/schemas/workspace/tiinex.workspace.v1.en.i18n.json +7 -0
  254. package/src/schemas/workspace/tiinex.workspace.v1.findings.js +5 -0
  255. package/src/schemas/workspace/tiinex.workspace.v1.presenter.js +27 -0
  256. package/src/schemas/workspace/tiinex.workspace.v1.schema.js +30 -0
  257. package/src/schemas/workspace/tiinex.workspace.v1.schema.json +23 -0
  258. package/src/schemas/workspace/tiinex.workspace.v1.schema.runtime.json +1596 -0
  259. package/src/schemas/workspace/tiinex.workspace.v1.schema.source.js +9 -0
  260. package/src/schemas/workspace/tiinex.workspace.v1.sv.i18n.json +7 -0
  261. package/src/schemas/workspace/tiinex.workspace.v1.transitions.js +10 -0
  262. package/src/schemas/workspace/tiinex.workspace.v1.validate.js +10 -0
  263. package/src/sources/github/github.issueTarget.js +127 -0
  264. package/src/sources/origin.references.js +249 -0
  265. package/src/sources/source.explicitTargets.js +49 -0
  266. package/src/sources/transport.levels.js +107 -0
  267. package/src/tooling/portable/adapters/cli/cli.cold-start-input.js +34 -0
  268. package/src/tooling/portable/adapters/cli/cli.command-input.js +455 -0
  269. package/src/tooling/portable/adapters/cli/cli.common-author.js +249 -0
  270. package/src/tooling/portable/adapters/cli/cli.common-output.js +330 -0
  271. package/src/tooling/portable/adapters/cli/cli.editor-assistance.js +13 -0
  272. package/src/tooling/portable/adapters/cli/cli.ground-materialize.js +96 -0
  273. package/src/tooling/portable/adapters/cli/cli.ground-recovery.js +99 -0
  274. package/src/tooling/portable/adapters/cli/cli.handoff-manufacture.js +345 -0
  275. package/src/tooling/portable/adapters/cli/cli.handoff-sibling-allocation.js +31 -0
  276. package/src/tooling/portable/adapters/cli/cli.help.js +80 -0
  277. package/src/tooling/portable/adapters/cli/cli.land.js +13 -0
  278. package/src/tooling/portable/adapters/cli/cli.local-output.js +72 -0
  279. package/src/tooling/portable/adapters/cli/cli.material-policy.js +6 -0
  280. package/src/tooling/portable/adapters/cli/cli.operator-bridge.js +18 -0
  281. package/src/tooling/portable/adapters/cli/cli.reduction-input.js +14 -0
  282. package/src/tooling/portable/adapters/cli/cli.run.js +434 -0
  283. package/src/tooling/portable/adapters/llm/llm.entrypoint.js +34 -0
  284. package/src/tooling/portable/adapters/node/checkpoint.verify.js +267 -0
  285. package/src/tooling/portable/adapters/node/handoff.manufacture.bootstrap.js +109 -0
  286. package/src/tooling/portable/adapters/node/handoff.manufacture.enumeration.js +94 -0
  287. package/src/tooling/portable/adapters/node/handoff.manufacture.js +193 -0
  288. package/src/tooling/portable/adapters/node/handoff.manufacture.multiRoot.js +49 -0
  289. package/src/tooling/portable/adapters/node/handoff.manufacture.packageParent.js +130 -0
  290. package/src/tooling/portable/adapters/node/handoff.manufacture.requirements.js +353 -0
  291. package/src/tooling/portable/adapters/node/handoff.manufacture.scope.js +147 -0
  292. package/src/tooling/portable/adapters/node/workspaceCarrier.manufacture.js +62 -0
  293. package/src/tooling/portable/assets/asset.operations.js +170 -0
  294. package/src/tooling/portable/audit/audit.capability.js +119 -0
  295. package/src/tooling/portable/bootstrap/artifact.result.selfverify.mjs +109 -0
  296. package/src/tooling/portable/bootstrap/bootstrap.case.mjs +43 -0
  297. package/src/tooling/portable/bootstrap/tiinex.llm.bootstrap.md +814 -0
  298. package/src/tooling/portable/bootstrap/tiinex.llm.bootstrap.pointer.json +25 -0
  299. package/src/tooling/portable/checkpoint/portable.checkpoint.js +89 -0
  300. package/src/tooling/portable/conformance/checkpoint.qualification.js +271 -0
  301. package/src/tooling/portable/draft/draft.create.js +389 -0
  302. package/src/tooling/portable/draft/draft.crud.js +175 -0
  303. package/src/tooling/portable/draft/draft.exact.js +173 -0
  304. package/src/tooling/portable/draft/draft.operations.js +265 -0
  305. package/src/tooling/portable/draft/draft.qualification.js +45 -0
  306. package/src/tooling/portable/draft/draft.set.js +193 -0
  307. package/src/tooling/portable/draft/draft.validation-context.js +7 -0
  308. package/src/tooling/portable/editor/authoring.parent.js +37 -0
  309. package/src/tooling/portable/editor/editor.assistance.js +221 -0
  310. package/src/tooling/portable/editor/staged.validation.js +96 -0
  311. package/src/tooling/portable/engine.facade.js +468 -0
  312. package/src/tooling/portable/findings.js +92 -0
  313. package/src/tooling/portable/grounding/grounding.capsule.js +128 -0
  314. package/src/tooling/portable/grounding/grounding.continuity.js +283 -0
  315. package/src/tooling/portable/grounding/grounding.participantAuthority.js +20 -0
  316. package/src/tooling/portable/grounding/grounding.planningContext.js +34 -0
  317. package/src/tooling/portable/grounding/grounding.readiness.authority.js +17 -0
  318. package/src/tooling/portable/grounding/grounding.readiness.js +316 -0
  319. package/src/tooling/portable/grounding/grounding.readiness.support.js +245 -0
  320. package/src/tooling/portable/grounding/grounding.sourceEvidence.js +71 -0
  321. package/src/tooling/portable/grounding/grounding.workContext.js +72 -0
  322. package/src/tooling/portable/grounding/grounding.workProvenance.js +153 -0
  323. package/src/tooling/portable/handoff/carrierLineage.js +214 -0
  324. package/src/tooling/portable/handoff/carrierProfile.js +54 -0
  325. package/src/tooling/portable/handoff/carrierProjection.js +193 -0
  326. package/src/tooling/portable/handoff/carrierProjection.routeQualification.js +228 -0
  327. package/src/tooling/portable/handoff/carrierProjection.shared.js +7 -0
  328. package/src/tooling/portable/handoff/carrierProjection.workspaces.js +54 -0
  329. package/src/tooling/portable/handoff/coldConsumerEntrypoint.js +185 -0
  330. package/src/tooling/portable/handoff/coldStartQualification.contract.js +184 -0
  331. package/src/tooling/portable/handoff/coldStartQualification.grounding.js +392 -0
  332. package/src/tooling/portable/handoff/coldStartQualification.js +22 -0
  333. package/src/tooling/portable/handoff/coldStartQualification.materials.js +364 -0
  334. package/src/tooling/portable/handoff/coldStartQualification.observation.js +220 -0
  335. package/src/tooling/portable/handoff/coldStartQualification.run.js +81 -0
  336. package/src/tooling/portable/handoff/coldStartQualification.shared.js +57 -0
  337. package/src/tooling/portable/handoff/coldStartRolePointers.js +39 -0
  338. package/src/tooling/portable/handoff/contextAudit.js +247 -0
  339. package/src/tooling/portable/handoff/contracts/tiinex.handoff.package.v1.schema.md +409 -0
  340. package/src/tooling/portable/handoff/handoffAuthoringPlan.js +35 -0
  341. package/src/tooling/portable/handoff/handoffEndpointProjection.js +61 -0
  342. package/src/tooling/portable/handoff/handoffLeafProjection.js +91 -0
  343. package/src/tooling/portable/handoff/humanOutputPresentation.js +21 -0
  344. package/src/tooling/portable/handoff/manufacture.js +84 -0
  345. package/src/tooling/portable/handoff/materialClosure.archiveV2.binding.js +72 -0
  346. package/src/tooling/portable/handoff/materialClosure.archiveV2.direct.js +160 -0
  347. package/src/tooling/portable/handoff/materialClosure.archiveV2.indexes.js +36 -0
  348. package/src/tooling/portable/handoff/materialClosure.archiveV2.js +247 -0
  349. package/src/tooling/portable/handoff/materialClosure.archiveV2.projectionProvider.js +44 -0
  350. package/src/tooling/portable/handoff/materialClosure.archiveV2.workspace.js +226 -0
  351. package/src/tooling/portable/handoff/materialClosure.descriptor.js +169 -0
  352. package/src/tooling/portable/handoff/materialClosure.inputBinding.js +372 -0
  353. package/src/tooling/portable/handoff/materialClosure.inputBinding.support.js +62 -0
  354. package/src/tooling/portable/handoff/materialClosure.materialized.js +143 -0
  355. package/src/tooling/portable/handoff/materialClosure.materials.js +116 -0
  356. package/src/tooling/portable/handoff/materialClosure.package.js +181 -0
  357. package/src/tooling/portable/handoff/materialClosure.plan.js +204 -0
  358. package/src/tooling/portable/handoff/materialClosure.readiness.js +36 -0
  359. package/src/tooling/portable/handoff/materialClosure.requirements.js +137 -0
  360. package/src/tooling/portable/handoff/operatorContextProjection.js +105 -0
  361. package/src/tooling/portable/handoff/pointerEntrypoint.js +138 -0
  362. package/src/tooling/portable/handoff/qualifiedHandoffFixture.js +34 -0
  363. package/src/tooling/portable/handoff/recipientV2.artifactFirst.build.js +321 -0
  364. package/src/tooling/portable/handoff/recipientV2.artifactFirst.closure.js +126 -0
  365. package/src/tooling/portable/handoff/recipientV2.artifactFirst.inspect.js +194 -0
  366. package/src/tooling/portable/handoff/recipientV2.artifactFirst.materials.js +207 -0
  367. package/src/tooling/portable/handoff/recipientV2.artifactFirst.projection.js +69 -0
  368. package/src/tooling/portable/handoff/recipientV2.artifactFirst.roles.js +166 -0
  369. package/src/tooling/portable/handoff/recipientV2.artifactFirst.routes.js +113 -0
  370. package/src/tooling/portable/handoff/recipientV2.artifactFirst.shared.js +87 -0
  371. package/src/tooling/portable/handoff/recipientV2.artifactFirst.workspaces.js +160 -0
  372. package/src/tooling/portable/handoff/recipientV2.artifactFirstPhase1.js +44 -0
  373. package/src/tooling/portable/handoff/recipientV2.artifactInspection.js +55 -0
  374. package/src/tooling/portable/handoff/recipientV2.artifacts.js +174 -0
  375. package/src/tooling/portable/handoff/recipientV2.coldProjection.js +24 -0
  376. package/src/tooling/portable/handoff/recipientV2.delivery.js +48 -0
  377. package/src/tooling/portable/handoff/recipientV2.endpointRolePointers.js +179 -0
  378. package/src/tooling/portable/handoff/recipientV2.entryContract.js +28 -0
  379. package/src/tooling/portable/handoff/recipientV2.humanOutput.js +78 -0
  380. package/src/tooling/portable/handoff/recipientV2.inspect.helpers.js +218 -0
  381. package/src/tooling/portable/handoff/recipientV2.inspect.js +194 -0
  382. package/src/tooling/portable/handoff/recipientV2.inspect.pathToken.js +9 -0
  383. package/src/tooling/portable/handoff/recipientV2.inspect.projection.js +58 -0
  384. package/src/tooling/portable/handoff/recipientV2.inspect.workspaces.js +177 -0
  385. package/src/tooling/portable/handoff/recipientV2.lineage.js +142 -0
  386. package/src/tooling/portable/handoff/recipientV2.packageV1.build.js +147 -0
  387. package/src/tooling/portable/handoff/recipientV2.packageV1.constants.js +4 -0
  388. package/src/tooling/portable/handoff/recipientV2.packageV1.contract.js +101 -0
  389. package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.helpers.js +126 -0
  390. package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.js +185 -0
  391. package/src/tooling/portable/handoff/recipientV2.packageV1.js +12 -0
  392. package/src/tooling/portable/handoff/recipientV2.packageV1.shared.js +24 -0
  393. package/src/tooling/portable/handoff/recipientV2.packageV1.workspaceProjection.js +22 -0
  394. package/src/tooling/portable/handoff/recipientV2.pointer.js +40 -0
  395. package/src/tooling/portable/handoff/recipientV2.routeSelection.js +16 -0
  396. package/src/tooling/portable/handoff/recipientV2.topology.helpers.js +20 -0
  397. package/src/tooling/portable/handoff/recipientV2.topology.js +320 -0
  398. package/src/tooling/portable/handoff/recipientV2.topology.materials.js +70 -0
  399. package/src/tooling/portable/handoff/recipientV2.topology.workspaces.js +193 -0
  400. package/src/tooling/portable/handoff/recipientV2.transportManifest.js +123 -0
  401. package/src/tooling/portable/handoff/recipientV2.workspaceRepresentation.js +163 -0
  402. package/src/tooling/portable/handoff/routeArtifactConformance.js +130 -0
  403. package/src/tooling/portable/handoff/toolingBootstrap.js +67 -0
  404. package/src/tooling/portable/handoff/transportCompanion.js +175 -0
  405. package/src/tooling/portable/handoff/workspaceByteProvider.archive.js +95 -0
  406. package/src/tooling/portable/handoff/workspaceByteProvider.js +271 -0
  407. package/src/tooling/portable/handoff/workspaceCarrier.manufacture.js +93 -0
  408. package/src/tooling/portable/handoff/workspaceLandingPlan.js +142 -0
  409. package/src/tooling/portable/handoff/workspacePackageSources.js +105 -0
  410. package/src/tooling/portable/handoff/workspaceQualifiedReference.js +10 -0
  411. package/src/tooling/portable/handoff/workspaceSourceIdentity.js +52 -0
  412. package/src/tooling/portable/handoff/workspaceTargetConformance.js +134 -0
  413. package/src/tooling/portable/host/host.capabilities.js +181 -0
  414. package/src/tooling/portable/host/tool.bindings.js +357 -0
  415. package/src/tooling/portable/host/tool.receiptNormalization.js +141 -0
  416. package/src/tooling/portable/index.js +52 -0
  417. package/src/tooling/portable/input/node.input.js +184 -0
  418. package/src/tooling/portable/input/portable.input.js +249 -0
  419. package/src/tooling/portable/lifecycle/lifecycle.action.js +11 -0
  420. package/src/tooling/portable/lifecycle/lifecycle.material.js +173 -0
  421. package/src/tooling/portable/lifecycle/lifecycle.operations.js +34 -0
  422. package/src/tooling/portable/lifecycle/lifecycle.readiness.js +247 -0
  423. package/src/tooling/portable/lineage/lineage.integrity.apply.audit.js +22 -0
  424. package/src/tooling/portable/lineage/lineage.integrity.apply.evidence.js +36 -0
  425. package/src/tooling/portable/lineage/lineage.integrity.apply.js +306 -0
  426. package/src/tooling/portable/lineage/lineage.integrity.apply.structure.js +178 -0
  427. package/src/tooling/portable/lineage/lineage.integrity.plan.js +377 -0
  428. package/src/tooling/portable/lineage/lineage.integrity.projection.human.js +82 -0
  429. package/src/tooling/portable/lineage/lineage.integrity.projection.js +349 -0
  430. package/src/tooling/portable/lineage/lineage.operations.js +32 -0
  431. package/src/tooling/portable/lineage/lineage.print.js +398 -0
  432. package/src/tooling/portable/lineage/lineage.print.render.js +88 -0
  433. package/src/tooling/portable/lineage/lineage.print.utils.js +58 -0
  434. package/src/tooling/portable/lineage/lineage.publicationProviderReceipts.js +141 -0
  435. package/src/tooling/portable/lineage/lineage.publicationQualification.js +183 -0
  436. package/src/tooling/portable/lineage/lineage.search.js +301 -0
  437. package/src/tooling/portable/live/live.artifact.js +192 -0
  438. package/src/tooling/portable/live/live.export.js +107 -0
  439. package/src/tooling/portable/live/live.lineage.closure.js +71 -0
  440. package/src/tooling/portable/live/live.lineage.js +338 -0
  441. package/src/tooling/portable/live/live.protocol.js +181 -0
  442. package/src/tooling/portable/materialization/durable.materialize.js +162 -0
  443. package/src/tooling/portable/materialization/epistemic.plan.js +239 -0
  444. package/src/tooling/portable/materialization/loaded.parent.js +54 -0
  445. package/src/tooling/portable/materialization/materialization.facade.js +30 -0
  446. package/src/tooling/portable/operation.catalog.js +393 -0
  447. package/src/tooling/portable/operation.catalog.package.js +183 -0
  448. package/src/tooling/portable/operation.result.js +25 -0
  449. package/src/tooling/portable/orchestration/task.prepare.js +191 -0
  450. package/src/tooling/portable/output/artifact.result.package.js +308 -0
  451. package/src/tooling/portable/output/deterministic.zip.js +88 -0
  452. package/src/tooling/portable/output/node.artifact-set.js +223 -0
  453. package/src/tooling/portable/output/node.draft.js +41 -0
  454. package/src/tooling/portable/output/node.zip.js +39 -0
  455. package/src/tooling/portable/output/recipientV2.zip.js +59 -0
  456. package/src/tooling/portable/overview/blockingCue.js +16 -0
  457. package/src/tooling/portable/overview/operatingOverview.js +413 -0
  458. package/src/tooling/portable/package/generation.binding.js +314 -0
  459. package/src/tooling/portable/package/generation.binding.projection.js +128 -0
  460. package/src/tooling/portable/package/material.graph.js +236 -0
  461. package/src/tooling/portable/package/runtime.package.js +321 -0
  462. package/src/tooling/portable/package/schema.transition.companion.js +196 -0
  463. package/src/tooling/portable/package/semantic.package.graph.js +272 -0
  464. package/src/tooling/portable/package/semantic.package.js +203 -0
  465. package/src/tooling/portable/package/semantic.package.schema-resolution.js +158 -0
  466. package/src/tooling/portable/package/semantic.package.transition-registry.js +189 -0
  467. package/src/tooling/portable/package/semantic.package.types.js +18 -0
  468. package/src/tooling/portable/providers/schema.bootstrap.provenance.js +10 -0
  469. package/src/tooling/portable/providers/schema.provider.qualification.js +52 -0
  470. package/src/tooling/portable/providers/schema.providers.js +458 -0
  471. package/src/tooling/portable/publication/runtime.publication.js +53 -0
  472. package/src/tooling/portable/qualification.js +150 -0
  473. package/src/tooling/portable/reduction/reduction.composition.js +229 -0
  474. package/src/tooling/portable/reduction/reduction.eligibility.helpers.js +258 -0
  475. package/src/tooling/portable/reduction/reduction.eligibility.js +191 -0
  476. package/src/tooling/portable/reduction/reduction.operations.js +30 -0
  477. package/src/tooling/portable/reduction/reduction.preflight.js +85 -0
  478. package/src/tooling/portable/reduction/reduction.shared.js +173 -0
  479. package/src/tooling/portable/schema/bootstrap/canonical.pack.js +24 -0
  480. package/src/tooling/portable/schema/bootstrap/docs-3988951208eb9a8926e84ab42625d4b42fa00c2d/party/role/tiinex.party.role.v1.schema.md +289 -0
  481. package/src/tooling/portable/schema/bootstrap/docs-3988951208eb9a8926e84ab42625d4b42fa00c2d/validation/report/tiinex.validation.report.v1.schema.md +300 -0
  482. package/src/tooling/portable/schema/bootstrap/qualified-local-root/tiinex.root.v1.runtime-projection.json +48 -0
  483. package/src/tooling/portable/schema/bootstrap/qualified-local-root/tiinex.root.v1.schema.md +865 -0
  484. package/src/tooling/portable/schema/contract.compile.js +406 -0
  485. package/src/tooling/portable/schema/contract.compile.utils.js +9 -0
  486. package/src/tooling/portable/schema/contract.constraints.js +117 -0
  487. package/src/tooling/portable/schema/contract.envelope.validate.js +177 -0
  488. package/src/tooling/portable/schema/contract.field-domain.compile.js +399 -0
  489. package/src/tooling/portable/schema/contract.field-domain.js +247 -0
  490. package/src/tooling/portable/schema/contract.field-shape.compile.js +34 -0
  491. package/src/tooling/portable/schema/contract.inheritance.inline.js +103 -0
  492. package/src/tooling/portable/schema/contract.inheritance.js +210 -0
  493. package/src/tooling/portable/schema/contract.inheritance.record.js +76 -0
  494. package/src/tooling/portable/schema/contract.machine-shape.js +309 -0
  495. package/src/tooling/portable/schema/contract.project.js +81 -0
  496. package/src/tooling/portable/schema/contract.semantic-resolution.js +82 -0
  497. package/src/tooling/portable/schema/contract.validate.js +0 -0
  498. package/src/tooling/portable/schema/lexical.shape.v1.js +338 -0
  499. package/src/tooling/portable/schema/llm.companion.js +108 -0
  500. package/src/tooling/portable/schema/named.declarations.js +162 -0
  501. package/src/tooling/portable/schema/ordinary.contract.js +193 -0
  502. package/src/tooling/portable/schema/ordinary.fields.js +205 -0
  503. package/src/tooling/portable/schema/qualifiedLocalRoot.projection.js +70 -0
  504. package/src/tooling/portable/schema/qualifiedLocalRoot.runtime.js +170 -0
  505. package/src/tooling/portable/schema/schema.contract.js +465 -0
  506. package/src/tooling/portable/schema/schema.guide.js +326 -0
  507. package/src/tooling/portable/schema/schema.snapshot.js +119 -0
  508. package/src/tooling/portable/session/portable.session.js +145 -0
  509. package/src/tooling/portable/transfer/transfer.plan.js +102 -0
  510. package/src/transitions/record.transitions.js +484 -0
  511. package/src/transitions/transition.validate.js +129 -0
  512. package/src/validation/findings.js +76 -0
  513. package/src/validation/validateArtifact.js +216 -0
  514. package/src/workspaces/workspace.entrypointCapability.js +44 -0
  515. package/src/workspaces/workspace.materialRole.js +242 -0
  516. package/src/workspaces/workspace.recordPaths.js +426 -0
  517. package/tools/tiinex-portable.mjs +6 -0
@@ -0,0 +1,101 @@
1
+ import { sealC14nV2Self } from '../../../integrity/integrity.c14nV2.js';
2
+ import { C14N_V2_VALIDATOR_TARGET } from '../../../integrity/integrity.methodReference.js';
3
+ import { finding } from './recipientV2.topology.materials.js';
4
+ import { RECIPIENT_V2_PACKAGE_V1_SCHEMA_TARGET } from './recipientV2.packageV1.constants.js';
5
+ import { RECIPIENT_V2_READ_PATH } from './recipientV2.topology.js';
6
+ import { RECIPIENT_V2_ROOT_SCHEMA_TARGET } from './recipientV2.artifacts.js';
7
+ import { field, markdownTarget, normalizeCreatedAt, sectionText, unquote, validCarrierDimension } from './recipientV2.packageV1.shared.js';
8
+ import { normalizeHandoffCarrierProfile, normalizeWorkspaceIds } from './carrierProfile.js';
9
+
10
+ export const HANDOFF_PACKAGE_ROLE = 'recipient-facing-handoff-carrier';
11
+ export const WORKSPACE_PACKAGE_ROLE = 'recipient-facing-workspace-carrier';
12
+ export const WORKSPACE_CARRIER_CANONICAL_BLOCKER = 'portable.handoff-package-v1.workspace-carrier.canonical-follow-through-required';
13
+
14
+ function routeProfileForRole(role = HANDOFF_PACKAGE_ROLE) {
15
+ return role === WORKSPACE_PACKAGE_ROLE
16
+ ? Object.freeze({ routePlacementRule: 'none', continueFromRule: 'none', preHandoffClosureRule: 'none' })
17
+ : Object.freeze({ routePlacementRule: 'authoritative-workspace-descended', continueFromRule: 'exact-package-local-handoff-pointer', preHandoffClosureRule: 'selected-pointer-carrier-ancestors' });
18
+ }
19
+
20
+ export function renderHandoffPackageV1(input = {}) {
21
+ const createdAt = normalizeCreatedAt(input.createdAt || '');
22
+ const lineage = input.carrierLineage || {};
23
+ const carrierProfile = normalizeHandoffCarrierProfile(input.carrierProfile || null);
24
+ const packageRole = [HANDOFF_PACKAGE_ROLE, WORKSPACE_PACKAGE_ROLE].includes(String(input.packageRole || '')) ? String(input.packageRole) : HANDOFF_PACKAGE_ROLE;
25
+ const routeProfile = routeProfileForRole(packageRole);
26
+ const workspaces = input.workspaces || [];
27
+ const workspaceBlocks = workspaces.map((workspace) => `- ${workspace.workspaceId}\n - Workspace Id: ${workspace.workspaceId}\n - Workspace Artifact: [${workspace.workspaceId} Workspace](${workspace.workspacePath})\n - Snapshot Path: [${workspace.workspaceId} Snapshot](${workspace.archivePath})\n - Workspace Artifact Inner Path: \`${workspace.sourceWorkspaceTargetInnerPath}\`\n - Snapshot Kind: exact-workspace-byte-tree-archive\n - Coverage: complete\n - Binding State: verified\n - Integrity Method: sha256\n - Integrity Value: ${workspace.archiveSha256}\n - Byte Size: ${workspace.archiveBytes || ''}`.replace(/\n - Byte Size: $/, '')).join('\n');
28
+ const unsigned = `# Continuity Context\n\n- Envelope Schema: [tiinex.root.v1](${RECIPIENT_V2_ROOT_SCHEMA_TARGET})\n- Current\n - Current Schema: [tiinex.handoff.package.v1](${RECIPIENT_V2_PACKAGE_V1_SCHEMA_TARGET})\n - Created At: ${createdAt}\n - Summary: Recipient-facing self-contained Handoff carrier identity, discovery, exact complete Workspace snapshot bindings, and fail-closed qualification boundary.\n\n---\n\n# Handoff Package\n\n## Package Identity\n\n- Package Role: ${packageRole}\n- Carrier Kind: self-contained\n\n## Bootstrap Exposure\n\n- Start Artifact: [Start](${input.startPath || RECIPIENT_V2_READ_PATH})\n${input.bootstrapPath ? `- Tooling Bootstrap Descriptor: [Bootstrap](${input.bootstrapPath})\n` : '- Tooling Bootstrap Descriptor: [Bootstrap](001-2-bootstrap.trace.md)\n'}- Bootstrap Rule: start-then-qualified-bootstrap\n\n## Workspace Snapshot Bindings\n\n${workspaceBlocks || '- none'}\n\n## Route Discovery\n\n- Route Placement Rule: ${routeProfile.routePlacementRule}\n- Continue-From Rule: ${routeProfile.continueFromRule}\n- Pre-Handoff Closure Rule: ${routeProfile.preHandoffClosureRule}\n\n## Carrier Continuity\n\n- Carrier Dimension: ${String(lineage.dimension || '001')}\n${lineage.parentDimension ? `- Parent Carrier Dimension: ${String(lineage.parentDimension)}\n` : ''}- Carrier Checkpoint: ${String(lineage.checkpointKind || 'progression')}\n${lineage.majorReason ? `- Major Reason: ${String(lineage.majorReason)}\n` : ''}- Carrier Profile Id: ${carrierProfile.id || 'none'}\n- Required Major Workspace Ids: ${carrierProfile.requiredMajorWorkspaceIds.length ? carrierProfile.requiredMajorWorkspaceIds.join(', ') : 'none'}\n\n## Qualification Boundary\n\n- Receiver Qualification: reverify-carried-authority-and-bytes\n- Failure Policy: fail-closed\n- Derived Inventory Authority: none\n\n## Interpretation Limits\n\n- Does Not Mean: package placement, discovery ancestry, or byte integrity creates Handoff, Workspace, Role, participation, acceptance, provenance, or Parent authority\n- Must Not Be Used To Claim: carrier convenience metadata overrides the authoritative contained artifacts or exact qualified source bytes\n- Generic Payload Boundary: bootstrap/cache payloads retain explicit External Payload ownership when required; complete Workspace snapshot binding is package-local only\n- Generic Representation Boundary: bounded, partial, independently selectable, multi-representation, or external-lifecycle Workspace representations require the generic Workspace Representation contract\n- Carrier Profile Boundary: required Workspace identifiers come only from the explicit carrier profile; literal project Workspace names have no generic semantic meaning\n\n---\n\n# Continuity Integrity\n\n- [sha256-base64url-c14n-v2](${C14N_V2_VALIDATOR_TARGET})\n - Towards: self\n - Value: pending\n`;
29
+ const sealed = sealC14nV2Self(unsigned);
30
+ if (sealed.state !== 'sealed') throw new Error(`portable.handoff-package-v1.integrity.seal-failed:${sealed.reason || sealed.state}`);
31
+ return `${sealed.markdown}\n`;
32
+ }
33
+
34
+ export function parseHandoffPackageV1(markdown = '') {
35
+ const body = String(markdown || '');
36
+ const workspaceHeading = '## Workspace Snapshot Bindings';
37
+ const workspaceStart = body.indexOf(workspaceHeading);
38
+ const workspaceEnd = workspaceStart >= 0 ? body.indexOf('## Route Discovery', workspaceStart + workspaceHeading.length) : -1;
39
+ const workspacesSection = workspaceStart >= 0 ? body.slice(workspaceStart + workspaceHeading.length, workspaceEnd >= 0 ? workspaceEnd : undefined).trim() : '';
40
+ const workspaces = parseWorkspaceBindings(workspacesSection);
41
+ return Object.freeze({
42
+ packageRole: field(sectionText(body, 'Package Identity'), 'Package Role'), carrierKind: field(sectionText(body, 'Package Identity'), 'Carrier Kind'),
43
+ startPath: markdownTarget(field(sectionText(body, 'Bootstrap Exposure'), 'Start Artifact')), bootstrapPath: markdownTarget(field(sectionText(body, 'Bootstrap Exposure'), 'Tooling Bootstrap Descriptor')), bootstrapRule: field(sectionText(body, 'Bootstrap Exposure'), 'Bootstrap Rule'),
44
+ workspaces: Object.freeze(workspaces), routePlacementRule: field(sectionText(body, 'Route Discovery'), 'Route Placement Rule'), continueFromRule: field(sectionText(body, 'Route Discovery'), 'Continue-From Rule'), preHandoffClosureRule: field(sectionText(body, 'Route Discovery'), 'Pre-Handoff Closure Rule'),
45
+ carrierDimension: field(sectionText(body, 'Carrier Continuity'), 'Carrier Dimension'), parentCarrierDimension: field(sectionText(body, 'Carrier Continuity'), 'Parent Carrier Dimension'), carrierCheckpoint: field(sectionText(body, 'Carrier Continuity'), 'Carrier Checkpoint'), majorReason: field(sectionText(body, 'Carrier Continuity'), 'Major Reason'), carrierProfileId: normalizeProfileId(field(sectionText(body, 'Carrier Continuity'), 'Carrier Profile Id')), requiredMajorWorkspaceIds: normalizeWorkspaceIds(field(sectionText(body, 'Carrier Continuity'), 'Required Major Workspace Ids')),
46
+ receiverQualification: field(sectionText(body, 'Qualification Boundary'), 'Receiver Qualification'), failurePolicy: field(sectionText(body, 'Qualification Boundary'), 'Failure Policy'), derivedInventoryAuthority: field(sectionText(body, 'Qualification Boundary'), 'Derived Inventory Authority')
47
+ });
48
+ }
49
+
50
+ export function validatePackageFields(value, findings) {
51
+ const packageRole = String(value?.packageRole || '');
52
+ const roleKnown = [HANDOFF_PACKAGE_ROLE, WORKSPACE_PACKAGE_ROLE].includes(packageRole);
53
+ if (!roleKnown) findings.push(finding('error', 'portable.handoff-package-v1.field.packageRole.invalid', 'Handoff package v1 Package Role is missing or invalid.', { field: 'packageRole', expected: `${HANDOFF_PACKAGE_ROLE}|${WORKSPACE_PACKAGE_ROLE}`, observed: packageRole }));
54
+ const routeProfile = routeProfileForRole(roleKnown ? packageRole : HANDOFF_PACKAGE_ROLE);
55
+ const exact = [
56
+ ['carrierKind', 'self-contained'], ['bootstrapRule', 'start-then-qualified-bootstrap'], ['routePlacementRule', routeProfile.routePlacementRule], ['continueFromRule', routeProfile.continueFromRule], ['preHandoffClosureRule', routeProfile.preHandoffClosureRule], ['receiverQualification', 'reverify-carried-authority-and-bytes'], ['failurePolicy', 'fail-closed'], ['derivedInventoryAuthority', 'none']
57
+ ];
58
+ for (const [key, expected] of exact) if (String(value?.[key] || '') !== expected) findings.push(finding('error', `portable.handoff-package-v1.field.${key}.invalid`, 'Handoff package v1 required closed-domain field is missing or invalid.', { field: key, expected, observed: String(value?.[key] || '') }));
59
+ if (!value?.startPath || !value?.bootstrapPath) findings.push(finding('error', 'portable.handoff-package-v1.bootstrap-exposure-invalid', 'Start Artifact and Tooling Bootstrap Descriptor must be package-local links.'));
60
+ if (!Array.isArray(value?.workspaces) || !value.workspaces.length) findings.push(finding('error', 'portable.handoff-package-v1.workspace-bindings-missing', 'Handoff package v1 requires at least one complete Workspace snapshot binding.'));
61
+ if (!validCarrierDimension(value?.carrierDimension)) findings.push(finding('error', 'portable.handoff-package-v1.carrier-dimension-invalid', 'Carrier Dimension must be a canonical numeric hyphen path.', { value: value?.carrierDimension || '' }));
62
+ if (value?.parentCarrierDimension && !validCarrierDimension(value.parentCarrierDimension)) findings.push(finding('error', 'portable.handoff-package-v1.parent-carrier-dimension-invalid', 'Parent Carrier Dimension must be a canonical numeric hyphen path.', { value: value.parentCarrierDimension || '' }));
63
+ if (!['progression', 'major'].includes(String(value?.carrierCheckpoint || ''))) findings.push(finding('error', 'portable.handoff-package-v1.carrier-checkpoint-invalid', 'Carrier Checkpoint must be progression or major.'));
64
+ if (value?.carrierCheckpoint === 'major' && !String(value.majorReason || '').trim()) findings.push(finding('error', 'portable.handoff-package-v1.major-reason-missing', 'Major carrier requires one meaningful Major Reason.'));
65
+ if (value?.carrierCheckpoint === 'major') {
66
+ if ((value.requiredMajorWorkspaceIds || []).length && !String(value.carrierProfileId || '').trim()) findings.push(finding('error', 'portable.handoff-package-v1.major-carrier-profile-missing', 'Named Major Workspace requirements require one explicit carrier profile id.'));
67
+ const carried = new Set((value?.workspaces || []).map((item) => String(item.workspaceId || '').trim().toLowerCase()).filter(Boolean));
68
+ const missing = normalizeWorkspaceIds(value.requiredMajorWorkspaceIds || []).filter((workspaceId) => !carried.has(workspaceId));
69
+ if (missing.length) findings.push(finding('error', 'portable.handoff-package-v1.major-source-closure-incomplete', 'Major package-v1 carrier is missing one or more Workspace snapshot bindings required by its explicit carrier profile.', { carrierProfileId: String(value.carrierProfileId || ''), missingWorkspaceIds: missing }));
70
+ }
71
+ }
72
+
73
+ function parseWorkspaceBindings(text = '') {
74
+ const out = [];
75
+ const re = /^-\s+([^\n]+)\n((?:\s{2}-\s+[^\n]+\n?)*)/gm;
76
+ for (const match of String(text || '').matchAll(re)) {
77
+ const current = { label: String(match[1] || '').trim() };
78
+ for (const line of String(match[2] || '').split('\n')) {
79
+ const fieldMatch = line.match(/^\s{2}-\s+([^:]+):\s*(.*)$/);
80
+ if (!fieldMatch) continue;
81
+ const key = fieldMatch[1].trim(); const value = fieldMatch[2].trim();
82
+ if (key === 'Workspace Id') current.workspaceId = value;
83
+ else if (key === 'Workspace Artifact') current.workspaceArtifactPath = markdownTarget(value);
84
+ else if (key === 'Snapshot Path') current.snapshotPath = markdownTarget(value);
85
+ else if (key === 'Workspace Artifact Inner Path') current.workspaceArtifactInnerPath = unquote(value);
86
+ else if (key === 'Snapshot Kind') current.snapshotKind = value;
87
+ else if (key === 'Coverage') current.coverage = value;
88
+ else if (key === 'Binding State') current.bindingState = value;
89
+ else if (key === 'Integrity Method') current.integrityMethod = value;
90
+ else if (key === 'Integrity Value') current.integrityValue = value;
91
+ else if (key === 'Byte Size') current.byteSize = /^\d+$/.test(value) ? Number(value) : null;
92
+ }
93
+ out.push(current);
94
+ }
95
+ return out.map((item) => Object.freeze({ ...item, byteSize: item.byteSize ?? null }));
96
+ }
97
+
98
+ function normalizeProfileId(value = '') {
99
+ const text = String(value || '').trim();
100
+ return text.toLowerCase() === 'none' ? '' : text;
101
+ }
@@ -0,0 +1,126 @@
1
+ import { packageFileBytes, sha256Hex } from '../../../export/package.bytes.js';
2
+ import { parseRecipientV2ExternalPayload, parseRecipientV2Pointer } from './recipientV2.artifacts.js';
3
+ import { RECIPIENT_V2_READ_PATH } from './recipientV2.topology.js';
4
+ import { RECIPIENT_V2_ROUTE_SELECTION_AUTHORITY, RECIPIENT_V2_SIBLING_ROUTE_INFERENCE } from './recipientV2.entryContract.js';
5
+ import { inspectStoredWorkspaceArchive } from './workspaceByteProvider.js';
6
+ import { parentTrace } from './recipientV2.lineage.js';
7
+ import { finding } from './recipientV2.topology.materials.js';
8
+ import { RECIPIENT_V2_PACKAGE_V1_FORMAT_ID, RECIPIENT_V2_PACKAGE_V1_ROOT_PATH } from './recipientV2.packageV1.constants.js';
9
+ import { currentSchemaId, decodeUtf8, field, markdownTarget, numericDimension, oneFile, sectionText, unquote } from './recipientV2.packageV1.shared.js';
10
+
11
+ export function validateRouteClosure(routePointers, endpointPointers, participantPointers, caches, workspaces, findings) {
12
+ const roles = new Map([...(endpointPointers || []), ...(participantPointers || [])].map((item) => [item.path, item]));
13
+ const cacheByPath = new Map((caches || []).map((item) => [item.artifact.path, item]));
14
+ const workspaceByPath = new Map((workspaces || []).map((item) => [item.artifact.path, item]));
15
+ for (const pointer of routePointers || []) {
16
+ const expectedWorkspace = workspaces.find((item) => item.workspaceId === String(pointer.facts?.workspaceId || ''));
17
+ if (!expectedWorkspace) continue;
18
+ let cursor = pointer;
19
+ const seen = new Set([pointer.path]);
20
+ const ancestorRoles = [];
21
+ let terminal = '';
22
+ while (cursor) {
23
+ const trace = parentTrace(cursor);
24
+ if (!trace || seen.has(trace)) break;
25
+ seen.add(trace);
26
+ if (roles.has(trace)) { cursor = roles.get(trace); ancestorRoles.push(trace); continue; }
27
+ if (cacheByPath.has(trace) || workspaceByPath.has(trace)) { terminal = trace; break; }
28
+ findings.push(finding('error', 'portable.handoff-package-v1.route-ancestor-unknown', 'Selected Handoff Pointer ancestor closure contains an unjustified package artifact role.', { pointer: pointer.path, ancestor: trace })); break;
29
+ }
30
+ const expectedTerminal = String(pointer.facts?.cacheArtifactPath || expectedWorkspace.artifact.path);
31
+ if (terminal !== expectedTerminal) findings.push(finding('error', 'portable.handoff-package-v1.route-ancestor-terminal-invalid', 'Selected Handoff Pointer ancestor closure must terminate at its bounded cache when present, otherwise its owning Workspace artifact.', { pointer: pointer.path, expectedTerminal, observedTerminal: terminal }));
32
+ for (const role of [...(endpointPointers || []), ...(participantPointers || [])].filter((item) => String(item.facts?.routeId || '') === String(pointer.facts?.routeId || ''))) if (!ancestorRoles.includes(role.path)) findings.push(finding('error', 'portable.handoff-package-v1.route-role-off-closure', 'Route-required Role Pointer must be on the selected Handoff Pointer ancestor closure.', { pointer: pointer.path, rolePointer: role.path }));
33
+ const wsDim = numericDimension(expectedWorkspace.artifact.path);
34
+ const pointerDim = numericDimension(pointer.path);
35
+ if (!wsDim || !pointerDim || !pointerDim.startsWith(`${wsDim}-`)) findings.push(finding('error', 'portable.handoff-package-v1.route-placement-invalid', 'Handoff Pointer numeric path must descend from the Workspace containing its authoritative Handoff target.', { pointer: pointer.path, workspace: expectedWorkspace.artifact.path }));
36
+ validateNumericParentChain(pointer, roles, cacheByPath, expectedWorkspace, findings);
37
+ }
38
+ }
39
+
40
+ function validateNumericParentChain(pointer, roles, cacheByPath, workspace, findings) {
41
+ let child = pointer;
42
+ const lookup = new Map([...roles, ...cacheByPath].map(([key, value]) => [key, value.artifact || value]));
43
+ lookup.set(workspace.artifact.path, workspace.artifact);
44
+ const seen = new Set();
45
+ while (child && !seen.has(child.path)) {
46
+ seen.add(child.path);
47
+ const trace = parentTrace(child);
48
+ if (!trace) break;
49
+ const childDim = numericDimension(child.path);
50
+ const parentDim = numericDimension(trace);
51
+ const expected = childDim.split('-').slice(0, -1).join('-');
52
+ if (!childDim || !parentDim || parentDim !== expected) findings.push(finding('error', 'portable.handoff-package-v1.numeric-lineage-invalid', 'Carrier-local route ancestor numeric dimensions must mirror declared Parent continuity without alphabetic lineage components.', { path: child.path, parent: trace, childDimension: childDim, parentDimension: parentDim, expectedParentDimension: expected }));
53
+ if (trace === workspace.artifact.path) break;
54
+ child = lookup.get(trace) || null;
55
+ }
56
+ }
57
+
58
+ export function deriveVisibleFacts({ markdown = '', schemaId = '', packageContract = null, index = new Map() } = {}) {
59
+ if (schemaId === 'tiinex.pointer.v1') {
60
+ const visible = parseRecipientV2Pointer(markdown);
61
+ const role = String(visible.role || '');
62
+ if (!role) return null;
63
+ const base = { factsFormat: 'portable-recipient-v2', factsVersion: 1, role };
64
+ if (role === 'recovery-orientation') { const workspaceMode = String(packageContract?.packageRole || '') === 'recipient-facing-workspace-carrier'; return { ...base, format: RECIPIENT_V2_PACKAGE_V1_FORMAT_ID, packageRole: String(packageContract?.packageRole || ''), packageRootPath: RECIPIENT_V2_PACKAGE_V1_ROOT_PATH, entryArtifactPath: RECIPIENT_V2_READ_PATH, routeAuthority: workspaceMode ? 'none' : 'qualified-handoff-route-pointer-plus-exact-handoff-bytes', routeSelectionAuthority: workspaceMode ? 'none' : RECIPIENT_V2_ROUTE_SELECTION_AUTHORITY, siblingRouteInference: workspaceMode ? false : RECIPIENT_V2_SIBLING_ROUTE_INFERENCE }; }
65
+ if (role === 'handoff-route') {
66
+ const workspaceId = String(visible.workspaceId || '');
67
+ const binding = (packageContract?.workspaces || []).find((item) => item.workspaceId === workspaceId) || null;
68
+ const archiveFile = binding ? oneFile(index, binding.snapshotPath) : null;
69
+ const workspaceFile = binding ? oneFile(index, binding.workspaceArtifactPath) : null;
70
+ const parsed = archiveFile ? inspectStoredWorkspaceArchive(packageFileBytes(archiveFile), { ownedBytes: true }) : null;
71
+ const handoffEntry = (parsed?.entries || []).find((entry) => entry.path === visible.handoffWorkspacePath) || null;
72
+ const current = sectionText(markdown, 'Current Read');
73
+ return { ...base, workspaceId, workspaceArtifactPath: binding?.workspaceArtifactPath || '', workspaceArtifactSha256: workspaceFile ? sha256Hex(packageFileBytes(workspaceFile)) : '', archivePath: binding?.snapshotPath || '', archiveSha256: archiveFile ? sha256Hex(packageFileBytes(archiveFile)) : '', sourceWorkspaceTargetInnerPath: binding?.workspaceArtifactInnerPath || '', sourceWorkspaceTargetSha256: workspaceFile ? sha256Hex(packageFileBytes(workspaceFile)) : '', workspaceRelativeHandoffPath: visible.handoffWorkspacePath, handoffBytes: Number(handoffEntry?.bytes || 0), handoffSha256: String(handoffEntry?.sha256 || ''), routeId: visible.routeId || unquote(field(current, 'Route Id')), cacheArtifactPath: markdownTarget(field(current, 'Workspace Dependency Cache')), requiredContextBindings: Object.freeze([]) };
74
+ }
75
+ if (role === 'endpoint-role' || role === 'participant-role') {
76
+ const targetPayload = visible.targetPayload || '';
77
+ const payload = oneFile(index, targetPayload);
78
+ let entry = null;
79
+ if (payload) {
80
+ const parsed = inspectStoredWorkspaceArchive(packageFileBytes(payload), { ownedBytes: true });
81
+ entry = (parsed.entries || []).find((item) => item.path === (visible.targetInnerPath || visible.targetArchiveEntry)) || null;
82
+ }
83
+ return { ...base, workspaceId: workspaceIdForRoute(index, visible.routeId || ''), routeId: visible.routeId || '', endpointRequirementId: visible.endpointRequirementId || '', participantRequirementId: visible.participantRequirementId || '', endpointParty: visible.endpointParty || '', roleLabelHint: visible.roleLabelHint || '', referenceTarget: visible.roleReference || '', targetCarrierKind: visible.targetCarrierKind || '', targetWorkspaceId: visible.targetWorkspaceId || '', archivePath: targetPayload, archiveSha256: payload ? sha256Hex(packageFileBytes(payload)) : '', targetInnerPath: visible.targetInnerPath || '', targetArchiveEntry: visible.targetArchiveEntry || '', targetBytes: Number(entry?.bytes || 0), targetSha256: String(entry?.sha256 || '') };
84
+ }
85
+ return base;
86
+ }
87
+ if (schemaId === 'tiinex.external.payload.v1') {
88
+ const visible = parseRecipientV2ExternalPayload(markdown);
89
+ const role = String(visible.payloadRole || '');
90
+ const parent = parentTraceFromMarkdown(markdown);
91
+ const workspaceId = String(visible.workspaceId || '') || (packageContract?.workspaces || []).find((item) => item.workspaceArtifactPath === parent)?.workspaceId || '';
92
+ const materials = parsePayloadMaterials(sectionText(markdown, 'Payload Material Bindings'));
93
+ return { factsFormat: 'portable-recipient-v2', factsVersion: 1, role, workspaceId, archivePath: visible.location, archiveBytes: visible.bytes, archiveSha256: visible.integrityValue, materials };
94
+ }
95
+ return null;
96
+ }
97
+
98
+ function workspaceIdForRoute(index = new Map(), routeId = '') {
99
+ const targetRouteId = String(routeId || '');
100
+ if (!targetRouteId) return '';
101
+ const matches = [];
102
+ for (const files of index.values()) for (const candidate of files || []) {
103
+ if (!/\.md$/i.test(String(candidate.path || ''))) continue;
104
+ const candidateMarkdown = decodeUtf8(packageFileBytes(candidate));
105
+ if (currentSchemaId(candidateMarkdown) !== 'tiinex.pointer.v1') continue;
106
+ const visible = parseRecipientV2Pointer(candidateMarkdown);
107
+ if (visible.role === 'handoff-route' && String(visible.routeId || '') === targetRouteId) matches.push(String(visible.workspaceId || ''));
108
+ }
109
+ const unique = [...new Set(matches.filter(Boolean))];
110
+ return unique.length === 1 ? unique[0] : '';
111
+ }
112
+
113
+ function parsePayloadMaterials(section = '') {
114
+ const lines = String(section || '').split('\n');
115
+ const out = []; let current = null;
116
+ for (const line of lines) {
117
+ const first = line.match(/^- Requirement Id:\s*(.+)$/);
118
+ if (first) { if (current) out.push(current); current = { requirementId: first[1].trim() }; continue; }
119
+ const match = line.match(/^\s{2}-\s+([^:]+):\s*(.*)$/); if (!current || !match) continue;
120
+ const key = match[1].trim(), value = match[2].trim();
121
+ if (key === 'Classification') current.classification = value; else if (key === 'Material Reference') current.referenceTarget = value; else if (key === 'Archive Entry') current.archiveEntry = value; else if (key === 'Route Workspace Id') current.routeWorkspaceId = value; else if (key === 'Route Path') current.routePath = value; else if (key === 'Source Requirement Id') current.sourceRequirementId = value; else if (key === 'Original Path') current.originalPath = value; else if (key === 'Byte Size') current.bytes = Number(value || 0); else if (key === 'SHA256') current.sha256 = value;
122
+ }
123
+ if (current) out.push(current);
124
+ return out;
125
+ }
126
+ function parentTraceFromMarkdown(markdown = '') { return String(markdown).match(/^\s*-\s+Trace:\s*\[[^\]]*\]\(([^)]+)\)\s*$/mi)?.[1] || ''; }
@@ -0,0 +1,185 @@
1
+ import { packageFileByteView, packageFileBytes, sha256Hex } from '../../../export/package.bytes.js';
2
+ import { canonicalC14nV2SelfState } from '../../../integrity/integrity.c14nV2.js';
3
+ import { buildHandoffCarrierProjection } from './carrierProjection.js';
4
+ import { buildHandoffWorkspaceByteProvider, inspectStoredWorkspaceArchive } from './workspaceByteProvider.js';
5
+ import { qualifyHandoffWorkspaceTarget } from './workspaceTargetConformance.js';
6
+ import { inspectRecipientV2Artifact, parseRecipientV2ExternalPayload, parseRecipientV2Facts } from './recipientV2.artifacts.js';
7
+ import { RECIPIENT_V2_READ_PATH } from './recipientV2.topology.js';
8
+ import { recipientColdProjection } from './recipientV2.coldProjection.js';
9
+ import { buildPackageLocalParentResolver, inspectEndpointRolePointers, inspectParticipantRolePointers, inspectRoutePointers, parentTrace } from './recipientV2.lineage.js';
10
+ import { finding } from './recipientV2.topology.materials.js';
11
+ import { indexRecipientFiles, recipientWorkspaceDescriptor, virtualCacheMaterial } from './recipientV2.inspect.helpers.js';
12
+ import { inspectPortableToolingBootstrap } from './toolingBootstrap.js';
13
+ import { projectRecipientV2EndpointRoles, projectRecipientV2ParticipantRoles, projectRecipientV2Routes } from './recipientV2.inspect.projection.js';
14
+ import { RECIPIENT_V2_PACKAGE_V1_FORMAT_ID, RECIPIENT_V2_PACKAGE_V1_ROOT_PATH, RECIPIENT_V2_PACKAGE_V1_SCHEMA_ID } from './recipientV2.packageV1.constants.js';
15
+ import { parseHandoffPackageV1, validatePackageFields, WORKSPACE_PACKAGE_ROLE } from './recipientV2.packageV1.contract.js';
16
+ import { deriveVisibleFacts, validateRouteClosure } from './recipientV2.packageV1.inspect.helpers.js';
17
+ import { workspaceCarrierProjection } from './recipientV2.packageV1.workspaceProjection.js';
18
+ import { byteEqual, currentSchemaId, decodeUtf8, dedupeFindings, deepFreeze, oneFile } from './recipientV2.packageV1.shared.js';
19
+
20
+ export function inspectRecipientFacingV2PackageV1(bundle = {}, options = {}) {
21
+ const files = Array.isArray(bundle.files) ? bundle.files : [];
22
+ const findings = [];
23
+ const index = indexRecipientFiles(files, findings);
24
+ for (const file of files) if (String(file.path || '').includes('/')) findings.push(finding('error', 'portable.handoff-package-v1.path-nonflat', 'Package v1 carrier root must be flat.', { path: file.path || '' }));
25
+ const packageCandidates = files.filter((file) => currentSchemaId(decodeUtf8(packageFileBytes(file))) === RECIPIENT_V2_PACKAGE_V1_SCHEMA_ID);
26
+ if (packageCandidates.length !== 1) findings.push(finding('error', 'portable.handoff-package-v1.package-artifact-count', 'Carrier must contain exactly one tiinex.handoff.package.v1 artifact.', { count: packageCandidates.length }));
27
+ const packageFile = packageCandidates[0] || null;
28
+ const packageMarkdown = packageFile ? decodeUtf8(packageFileBytes(packageFile)) : '';
29
+ const packageContract = packageFile ? parseHandoffPackageV1(packageMarkdown) : null;
30
+ if (packageFile) {
31
+ if (!/^\d{3}-tiinex-handoff-package\.trace\.md$/.test(String(packageFile.path || ''))) findings.push(finding('error', 'portable.handoff-package-v1.filename-invalid', 'Handoff package artifact filename must expose exactly one numeric package-root dimension.', { path: packageFile.path || '' }));
32
+ const self = canonicalC14nV2SelfState(packageMarkdown);
33
+ if (self.state !== 'verified') findings.push(finding('error', 'portable.handoff-package-v1.integrity-self-invalid', 'Handoff package artifact self-integrity must independently verify.', { reason: self.reason || self.state }));
34
+ validatePackageFields(packageContract, findings);
35
+ }
36
+
37
+ const generatedArtifacts = [];
38
+ const resolveParent = buildPackageLocalParentResolver(index);
39
+ for (const file of files) {
40
+ if (!/\.md$/i.test(String(file.path || '')) || file === packageFile) continue;
41
+ const markdown = decodeUtf8(packageFileBytes(file));
42
+ const schemaId = currentSchemaId(markdown);
43
+ const facts = file.transportFacts || parseRecipientV2Facts(markdown) || deriveVisibleFacts({ file, markdown, schemaId, packageContract, index });
44
+ if (schemaId === 'tiinex.workspace.v1' && !facts) continue;
45
+ if (schemaId === 'tiinex.party.role.v1') { findings.push(finding('error', 'portable.handoff-package-v1.detached-role-copy', 'Package root must not carry detached Role artifacts; route grounding uses Role Pointers to exact Workspace/cache bytes.', { path: file.path || '' })); continue; }
46
+ if (!facts) { findings.push(finding('error', 'portable.handoff-package-v1.unknown-artifact-role', 'Package root contains Markdown whose semantic carrier role is not justified by package v1.', { path: file.path || '', schemaId })); continue; }
47
+ const artifact = inspectRecipientV2Artifact(file, { facts, resolveParent });
48
+ generatedArtifacts.push(artifact);
49
+ findings.push(...artifact.findings);
50
+ }
51
+ const readArtifact = generatedArtifacts.find((item) => item.path === packageContract?.startPath && item.schemaId === 'tiinex.pointer.v1' && item.facts?.role === 'recovery-orientation') || null;
52
+ if (!readArtifact) findings.push(finding('error', 'portable.handoff-package-v1.start-unresolved', 'Start Artifact must resolve to one qualified recovery/orientation Pointer.'));
53
+ else if (packageFile && parentTrace(readArtifact) !== packageFile.path) findings.push(finding('error', 'portable.handoff-package-v1.start-parent-mismatch', 'Start Artifact must descend directly from the package artifact.', { observedParent: parentTrace(readArtifact), expectedParent: packageFile.path }));
54
+
55
+ const bindings = packageContract?.workspaces || [];
56
+ const workspaceParts = [];
57
+ const workspaceDescriptors = [];
58
+ const virtualWorkspaceTargets = [];
59
+ for (const binding of bindings) {
60
+ const workspaceFile = oneFile(index, binding.workspaceArtifactPath);
61
+ const archiveFile = oneFile(index, binding.snapshotPath);
62
+ if (!workspaceFile || !archiveFile) { findings.push(finding('error', 'portable.handoff-package-v1.workspace-binding-unresolved', 'Workspace binding paths must resolve exactly once inside the package.', { workspaceId: binding.workspaceId })); continue; }
63
+ const workspaceMarkdown = decodeUtf8(packageFileBytes(workspaceFile));
64
+ if (currentSchemaId(workspaceMarkdown) !== 'tiinex.workspace.v1') findings.push(finding('error', 'portable.handoff-package-v1.workspace-schema-invalid', 'Workspace Artifact must declare tiinex.workspace.v1.', { workspaceId: binding.workspaceId, path: workspaceFile.path || '' }));
65
+ if (String(binding.snapshotKind || '') !== 'exact-workspace-byte-tree-archive' || String(binding.coverage || '') !== 'complete' || String(binding.bindingState || '') !== 'verified' || String(binding.integrityMethod || '') !== 'sha256') findings.push(finding('error', 'portable.handoff-package-v1.workspace-binding-contract-invalid', 'Qualified package v1 Workspace binding requires exact complete verified sha256 semantics.', { workspaceId: binding.workspaceId }));
66
+ const archiveData = packageFileByteView(archiveFile);
67
+ const archiveSha = sha256Hex(archiveData);
68
+ if (archiveSha !== binding.integrityValue) findings.push(finding('error', 'portable.handoff-package-v1.workspace-snapshot-digest-mismatch', 'Workspace Snapshot Integrity Value diverges from exact carried bytes.', { workspaceId: binding.workspaceId }));
69
+ if (binding.byteSize !== null && Number(binding.byteSize) !== archiveData.byteLength) findings.push(finding('error', 'portable.handoff-package-v1.workspace-snapshot-size-mismatch', 'Workspace Snapshot Byte Size diverges from exact carried bytes.', { workspaceId: binding.workspaceId }));
70
+ const parsed = inspectStoredWorkspaceArchive(archiveData, { ownedBytes: true });
71
+ if (parsed.state !== 'qualified') { findings.push(finding('error', 'portable.handoff-package-v1.workspace-snapshot-invalid', 'Workspace Snapshot failed safe normalized archive qualification.', { workspaceId: binding.workspaceId })); continue; }
72
+ const inner = (parsed.entries || []).filter((entry) => entry.path === binding.workspaceArtifactInnerPath);
73
+ if (inner.length !== 1) { findings.push(finding('error', 'portable.handoff-package-v1.workspace-inner-unresolved', 'Workspace Artifact Inner Path must resolve exactly once.', { workspaceId: binding.workspaceId, count: inner.length })); continue; }
74
+ const workspaceData = packageFileByteView(workspaceFile);
75
+ const innerData = packageFileByteView({ data: inner[0].data });
76
+ if (!byteEqual(workspaceData, innerData)) findings.push(finding('error', 'portable.handoff-package-v1.workspace-inner-byte-mismatch', 'Carried Workspace Artifact bytes must exactly equal the selected snapshot inner entry.', { workspaceId: binding.workspaceId }));
77
+ const targetQualification = qualifyHandoffWorkspaceTarget({ targetPath: binding.workspaceArtifactInnerPath, targetData: workspaceData, entries: parsed.entries || [] });
78
+ if (targetQualification.state !== 'qualified') findings.push(finding('error', 'portable.handoff-package-v1.workspace-target-unqualified', 'Exact bound Workspace Artifact does not qualify.', { workspaceId: binding.workspaceId, reasons: targetQualification.reasons || [] }));
79
+ const descriptorPart = recipientWorkspaceDescriptor({ workspaceId: binding.workspaceId, facts: { providerKind: 'package-local-stored-zip-v1' }, representation: { workspaceArtifactInnerPath: binding.workspaceArtifactInnerPath, coverage: 'complete' }, payload: { location: binding.snapshotPath }, entries: parsed.entries || [], targetMarkdown: workspaceMarkdown, targetPackagePath: binding.workspaceArtifactPath, targetFile: { bytes: workspaceData.byteLength, sha256: sha256Hex(workspaceData) }, archiveFile: { path: archiveFile.path, bytes: archiveData.byteLength, sha256: archiveSha } });
80
+ workspaceDescriptors.push(descriptorPart);
81
+ workspaceParts.push({ workspaceId: binding.workspaceId, artifact: Object.freeze({ path: workspaceFile.path, sha256: sha256Hex(workspaceData), markdown: workspaceMarkdown }), facts: { workspaceId: binding.workspaceId, sourceWorkspaceTargetInnerPath: binding.workspaceArtifactInnerPath, sourceWorkspaceTargetSha256: sha256Hex(workspaceData) }, archiveFile, archive: { archive: parsed, sha256: archiveSha }, targetQualification });
82
+ virtualWorkspaceTargets.push(workspaceFile);
83
+ }
84
+
85
+ const payloadArtifacts = generatedArtifacts.filter((item) => item.schemaId === 'tiinex.external.payload.v1' && item.status === 'qualified');
86
+ const bootstrapArtifacts = payloadArtifacts.filter((item) => item.facts?.role === 'portable Tooling bootstrap runtime for recipient orientation and verification');
87
+ const cacheArtifacts = payloadArtifacts.filter((item) => item.facts?.role === 'workspace-scoped Handoff dependency cache');
88
+ const forbiddenWorkspacePayloads = payloadArtifacts.filter((item) => item.facts?.role === 'workspace-representation-payload');
89
+ if (forbiddenWorkspacePayloads.length) findings.push(finding('error', 'portable.handoff-package-v1.workspace-payload-redundant', 'Complete package-local Workspace bindings must not carry redundant Workspace External Payload companions.', { count: forbiddenWorkspacePayloads.length }));
90
+ if (generatedArtifacts.some((item) => item.schemaId === 'tiinex.workspace.representation.v1' || item.schemaId === 'tiinex.relation.v1')) findings.push(finding('error', 'portable.handoff-package-v1.workspace-representation-redundant', 'Complete package-local Workspace bindings must not carry redundant Workspace Representation/Relation companions.'));
91
+
92
+ let bootstrapInspection = null;
93
+ if (packageContract?.bootstrapPath) {
94
+ const bootstrapArtifact = bootstrapArtifacts.find((item) => item.path === packageContract.bootstrapPath) || null;
95
+ if (!bootstrapArtifact) findings.push(finding('error', 'portable.handoff-package-v1.bootstrap-unresolved', 'Tooling Bootstrap Descriptor must resolve to one qualified bootstrap External Payload artifact.'));
96
+ else {
97
+ const payload = parseRecipientV2ExternalPayload(bootstrapArtifact.markdown);
98
+ const zip = oneFile(index, payload.location);
99
+ if (!zip || payload.integrityMethod !== 'sha256' || payload.integrityValue !== (zip ? sha256Hex(packageFileBytes(zip)) : '')) findings.push(finding('error', 'portable.handoff-package-v1.bootstrap-payload-invalid', 'Tooling bootstrap descriptor/payload byte identity failed qualification.'));
100
+ else {
101
+ const parsed = inspectStoredWorkspaceArchive(packageFileBytes(zip), { ownedBytes: true });
102
+ if (parsed.state === 'qualified') {
103
+ bootstrapInspection = inspectPortableToolingBootstrap({ files: (parsed.entries || []).map((entry) => Object.freeze({ path: `tiinex.bootstrap/${entry.path}`, data: entry.data })) });
104
+ if (bootstrapInspection.status !== 'valid') findings.push(finding('error', 'portable.handoff-package-v1.bootstrap-runtime-unqualified', 'Tooling bootstrap payload failed embedded runtime qualification.'));
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ const caches = [];
111
+ for (const artifact of cacheArtifacts) {
112
+ const payload = parseRecipientV2ExternalPayload(artifact.markdown);
113
+ const file = oneFile(index, payload.location);
114
+ if (!file) { findings.push(finding('error', 'portable.handoff-package-v1.cache-payload-missing', 'Cache descriptor payload location is unresolved.', { path: artifact.path })); continue; }
115
+ const parsed = inspectStoredWorkspaceArchive(packageFileBytes(file), { ownedBytes: true });
116
+ if (parsed.state !== 'qualified') findings.push(finding('error', 'portable.handoff-package-v1.cache-payload-invalid', 'Cache payload is not a qualified safe stored ZIP.', { path: file.path }));
117
+ caches.push({ artifact, file, facts: artifact.facts || {}, archive: { archive: parsed, sha256: sha256Hex(packageFileBytes(file)) } });
118
+ }
119
+ const virtualCacheParts = caches.map((cache) => virtualCacheMaterial(cache, findings));
120
+ const virtualCache = { files: Object.freeze(virtualCacheParts.flatMap((item) => item.files || [])), materialized: Object.freeze(virtualCacheParts.flatMap((item) => item.materialized || [])) };
121
+
122
+ const descriptor = deepFreeze({ schema: 'tiinex.transport.handoff-material-closure-descriptor.v2', version: 2, workspaceMaterializations: Object.freeze(workspaceDescriptors.map((item) => item.workspace)), workspaceArchiveBindings: Object.freeze(workspaceDescriptors.map((item) => item.binding)), materialized: Object.freeze(virtualCache.materialized), requirements: Object.freeze({ required: Object.freeze([]), reference: Object.freeze([]), endpointRoles: Object.freeze([]), participantRoles: Object.freeze([]), dependencies: Object.freeze([]) }) });
123
+ const semanticBundle = { ...bundle, files: Object.freeze([...files, ...virtualCache.files]) };
124
+ const workspaceByteProvider = buildHandoffWorkspaceByteProvider(semanticBundle, descriptor);
125
+ findings.push(...(workspaceByteProvider.findings || []));
126
+
127
+ const routePointers = generatedArtifacts.filter((item) => item.schemaId === 'tiinex.pointer.v1' && item.facts?.role === 'handoff-route' && item.status === 'qualified');
128
+ const endpointRolePointers = generatedArtifacts.filter((item) => item.schemaId === 'tiinex.pointer.v1' && item.facts?.role === 'endpoint-role' && item.status === 'qualified');
129
+ const participantRolePointers = generatedArtifacts.filter((item) => item.schemaId === 'tiinex.pointer.v1' && item.facts?.role === 'participant-role' && item.status === 'qualified');
130
+ const lineage = packageContract ? Object.freeze({ dimension: packageContract.carrierDimension, parentDimension: packageContract.parentCarrierDimension, checkpointKind: packageContract.carrierCheckpoint, majorReason: packageContract.majorReason || '' }) : null;
131
+ const workspaceMode = String(packageContract?.packageRole || '') === WORKSPACE_PACKAGE_ROLE;
132
+ let carrierProjection;
133
+ if (workspaceMode) {
134
+ if (routePointers.length || endpointRolePointers.length || participantRolePointers.length || caches.length) findings.push(finding('error', 'portable.handoff-package-v1.workspace-carrier.handoff-surface-present', 'Pointerless Workspace carrier must not expose Handoff route, Role pointer, or Handoff cache carriers.', { routes: routePointers.length, endpointRoles: endpointRolePointers.length, participantRoles: participantRolePointers.length, caches: caches.length }));
135
+ carrierProjection = workspaceCarrierProjection(workspaceParts, lineage);
136
+ } else {
137
+ inspectEndpointRolePointers(endpointRolePointers, workspaceParts, caches, findings);
138
+ inspectParticipantRolePointers(participantRolePointers, workspaceParts, caches, findings);
139
+ const routeSpecs = routePointers.map((pointer) => ({ workspaceId: String(pointer.facts?.workspaceId || ''), path: String(pointer.facts?.workspaceRelativeHandoffPath || ''), purpose: '' }));
140
+ carrierProjection = buildHandoffCarrierProjection({ bundle: semanticBundle, descriptor, workspaceByteProvider, carrierLineage: lineage, routes: routeSpecs });
141
+ if (carrierProjection.status !== 'ready') findings.push(finding('error', 'portable.handoff-package-v1.routes-unqualified', 'Selected Handoff Pointer does not independently resolve to qualified authoritative Handoff bytes.', { causes: carrierProjection.findings || [] }));
142
+ inspectRoutePointers(routePointers, carrierProjection, workspaceParts, endpointRolePointers, participantRolePointers, index, findings);
143
+ validateRouteClosure(routePointers, endpointRolePointers, participantRolePointers, caches, workspaceParts, findings);
144
+ if (routePointers.length !== 1) findings.push(finding('error', 'portable.handoff-package-v1.route-count-invalid', 'Qualified Handoff-carrier package-v1 delivery requires exactly one selected Handoff Pointer.', { count: routePointers.length }));
145
+ for (const route of carrierProjection.routes || []) {
146
+ if (route.requiredClosure?.state !== 'qualified') findings.push(finding('error', 'portable.handoff-package-v1.required-closure-unqualified', 'Authoritative Handoff Required Context is not fully carried by exact Workspace snapshots or bounded cache.', { routeId: route.id || '' }));
147
+ for (const requirement of route.requiredClosure?.requirements || []) if (requirement.state === 'qualified' && !['workspace-archive-entry', 'materialized-required-material'].includes(String(requirement.resolution?.kind || ''))) findings.push(finding('error', 'portable.handoff-package-v1.external-closure-asset', 'Selected route closure requires a carrier kind not owned by complete Workspace snapshots or bounded cache.', { routeId: route.id || '', requirementId: requirement.requirementId || '', kind: requirement.resolution?.kind || '' }));
148
+ }
149
+ const allowedCacheRequirementIds = new Set();
150
+ for (const route of carrierProjection.routes || []) for (const requirement of route.requiredClosure?.requirements || []) if (requirement.requirementId) allowedCacheRequirementIds.add(String(requirement.requirementId));
151
+ for (const pointer of endpointRolePointers) if (pointer.facts?.endpointRequirementId) allowedCacheRequirementIds.add(String(pointer.facts.endpointRequirementId));
152
+ for (const pointer of participantRolePointers) if (pointer.facts?.participantRequirementId) allowedCacheRequirementIds.add(String(pointer.facts.participantRequirementId));
153
+ for (const cache of caches) for (const material of cache.facts?.materials || []) {
154
+ const requirementId = String(material.sourceRequirementId || material.requirementId || '');
155
+ if (!requirementId || !allowedCacheRequirementIds.has(requirementId)) findings.push(finding('error', 'portable.handoff-package-v1.cache-over-expansion', 'Workspace dependency cache contains material not required by the selected Handoff route closure.', { cache: cache.artifact.path, requirementId }));
156
+ }
157
+ }
158
+
159
+ const knownPaths = new Set([
160
+ packageFile?.path,
161
+ packageContract?.startPath,
162
+ ...(bindings || []).flatMap((binding) => [binding.workspaceArtifactPath, binding.snapshotPath]),
163
+ ...generatedArtifacts.filter((item) => ['recovery-orientation', 'handoff-route', 'endpoint-role', 'participant-role'].includes(String(item.facts?.role || ''))).map((item) => item.path),
164
+ ...bootstrapArtifacts.flatMap((artifact) => [artifact.path, parseRecipientV2ExternalPayload(artifact.markdown).location]),
165
+ ...caches.flatMap((cache) => [cache.artifact.path, cache.file.path])
166
+ ].filter(Boolean));
167
+ for (const file of files) {
168
+ const filePath = String(file.path || '');
169
+ if (/\.json$/i.test(filePath)) findings.push(finding('error', 'portable.handoff-package-v1.parallel-truth-json', 'Package-v1 carrier must not contain receipt.json, manifest.json, or equivalent root-level JSON parallel semantic truth.', { path: filePath }));
170
+ if (!knownPaths.has(filePath)) findings.push(finding('error', 'portable.handoff-package-v1.unknown-package-artifact', 'Package root contains an artifact whose carrier semantic role is not justified by package-v1 bindings or selected route closure.', { path: filePath }));
171
+ }
172
+ const finalFindings = dedupeFindings(findings);
173
+ const status = finalFindings.some((item) => item.severity === 'error') ? 'invalid' : 'valid';
174
+ const coldConsumerProjection = recipientColdProjection(carrierProjection, RECIPIENT_V2_READ_PATH);
175
+ return deepFreeze({
176
+ schema: 'tiinex.portable.recipient-facing-handoff-package-v1.inspection.v1', detected: Boolean(packageFile), status, format: RECIPIENT_V2_PACKAGE_V1_FORMAT_ID,
177
+ rootArtifact: packageFile ? Object.freeze({ path: packageFile.path, schemaId: RECIPIENT_V2_PACKAGE_V1_SCHEMA_ID, sha256: sha256Hex(packageFileBytes(packageFile)), carrierLineage: lineage }) : null,
178
+ readArtifact, workspaces: Object.freeze(workspaceParts.map((item) => Object.freeze({ workspaceId: item.workspaceId, coverage: 'complete', workspaceArtifactPath: item.artifact.path, workspaceArchivePath: item.archiveFile.path, sourceWorkspaceTargetInnerPath: item.facts.sourceWorkspaceTargetInnerPath, sourceWorkspaceTargetSha256: item.facts.sourceWorkspaceTargetSha256 }))),
179
+ routes: projectRecipientV2Routes(routePointers, endpointRolePointers, participantRolePointers), endpointRoles: projectRecipientV2EndpointRoles(endpointRolePointers), participantRoles: projectRecipientV2ParticipantRoles(participantRolePointers),
180
+ caches: Object.freeze(caches.map((cache) => Object.freeze({ workspaceId: String(cache.facts?.workspaceId || ''), artifactPath: cache.artifact.path, archivePath: cache.file.path, materials: cache.facts.materials || [] }))),
181
+ bootstrapInspection, transportManifest: null, artifactFacts: Object.freeze(generatedArtifacts.map((item) => Object.freeze({ path: item.path, facts: item.facts }))), descriptor, workspaceByteProvider, carrierProjection, coldConsumerProjection,
182
+ packageContract, findings: Object.freeze(finalFindings), findingSummary: Object.freeze({ errors: finalFindings.filter((item) => item.severity === 'error').length, findings: finalFindings.length }),
183
+ boundary: 'Read-only qualification of tiinex.handoff.package.v1: visible package identity/discovery and complete package-local Workspace bindings are reverified from exact bytes; derived inventories have no authority.'
184
+ });
185
+ }
@@ -0,0 +1,12 @@
1
+ import { packageFileBytes } from '../../../export/package.bytes.js';
2
+ import { RECIPIENT_V2_PACKAGE_V1_SCHEMA_ID } from './recipientV2.packageV1.constants.js';
3
+ import { currentSchemaId, decodeUtf8 } from './recipientV2.packageV1.shared.js';
4
+
5
+ export { RECIPIENT_V2_PACKAGE_V1_FORMAT_ID, RECIPIENT_V2_PACKAGE_V1_ROOT_PATH, RECIPIENT_V2_PACKAGE_V1_SCHEMA_ID, RECIPIENT_V2_PACKAGE_V1_SCHEMA_TARGET } from './recipientV2.packageV1.constants.js';
6
+ export { buildRecipientFacingV2PackageV1 } from './recipientV2.packageV1.build.js';
7
+ export { inspectRecipientFacingV2PackageV1 } from './recipientV2.packageV1.inspect.js';
8
+ export { parseHandoffPackageV1, renderHandoffPackageV1 } from './recipientV2.packageV1.contract.js';
9
+
10
+ export function isRecipientV2PackageV1Surface(files = []) {
11
+ return files.some((file) => /\.md$/i.test(String(file.path || '')) && currentSchemaId(decodeUtf8(packageFileBytes(file))) === RECIPIENT_V2_PACKAGE_V1_SCHEMA_ID);
12
+ }
@@ -0,0 +1,24 @@
1
+ import { finalizeFile } from '../../../export/package.fileMap.js';
2
+ import { packageFileByteView } from '../../../export/package.bytes.js';
3
+ import { finding } from './recipientV2.topology.materials.js';
4
+
5
+ export function exactFile(path, data, logicalKind, mediaType) {
6
+ return finalizeFile({ path, requestedPath: path, kind: logicalKind, logicalKind, mediaType, data: packageFileByteView({ data }) });
7
+ }
8
+ export function workspaceSchemaTarget(qualification = {}) {
9
+ return String(qualification?.schemaTarget || '') || 'https://github.com/Tiinex/docs/blob/3988951208eb9a8926e84ab42625d4b42fa00c2d/.topics/.schemas/coordination/workspace/tiinex.workspace.v1.schema.md';
10
+ }
11
+ export function oneFile(index, path) { const list = index.get(String(path || '')) || []; return list.length === 1 ? list[0] : null; }
12
+ export function validCarrierDimension(value = '') { return /^\d{3}(?:-(?:[1-9]\d*))*$/.test(String(value || '')); }
13
+ export function numericDimension(path = '') { return String(path || '').match(/^(\d{3}(?:-[1-9]\d*)*)-/)?.[1] || ''; }
14
+ export function currentSchemaId(markdown = '') { return String(markdown || '').match(/^\s*-\s+Current Schema:\s*(?:\[)?(tiinex\.[A-Za-z0-9._-]+)(?:\])?/mi)?.[1] || ''; }
15
+ export function sectionText(markdown = '', title = '') { const source = String(markdown || ''); const escaped = title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const match = source.match(new RegExp(`^##\\s+${escaped}\\s*$([\\s\\S]*?)(?=^##\\s+|^#\\s+Continuity Integrity\\s*$|\\Z)`, 'mi')); return match ? match[1] : ''; }
16
+ export function field(section = '', label = '') { const escaped = label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); return String(section || '').match(new RegExp(`^\\s*-\\s+${escaped}:\\s*(.*?)\\s*$`, 'mi'))?.[1]?.trim() || ''; }
17
+ export function markdownTarget(value = '') { const match = String(value || '').match(/\[[^\]]*\]\(([^)]+)\)/); return match ? match[1].trim() : ''; }
18
+ export function unquote(value = '') { const text = String(value || '').trim(); return text.startsWith('`') && text.endsWith('`') ? text.slice(1, -1) : text; }
19
+ export function byteEqual(a, b) { if (a.byteLength !== b.byteLength) return false; for (let i = 0; i < a.byteLength; i += 1) if (a[i] !== b[i]) return false; return true; }
20
+ export function normalizeCreatedAt(value = '') { const text = String(value || '').trim(); if (!text) return '1970-01-01 00:00:00'; return text.replace('T', ' ').replace(/\.\d{3}Z$/, '').replace(/Z$/, '').slice(0, 19); }
21
+ export function decodeUtf8(data) { try { return new TextDecoder('utf-8', { fatal: true }).decode(data); } catch { return ''; } }
22
+ export function dedupeFindings(items = []) { const map = new Map(); for (const item of items) { const key = `${item.severity || ''}:${item.code || ''}:${item.workspaceId || ''}:${item.path || ''}:${item.pointer || ''}:${item.rolePointer || ''}`; if (!map.has(key)) map.set(key, item); } return [...map.values()]; }
23
+ export function blocked(reason, findings = []) { return Object.freeze({ status: 'blocked', files: Object.freeze([]), topology: Object.freeze({}), inspection: null, findings: Object.freeze([...(findings || []), finding('error', `portable.handoff-package-v1.${reason}`, 'Recipient-facing package-v1 construction failed closed.')]), boundary: 'Package-v1 construction failed closed before exposing a recipient carrier.' }); }
24
+ export function deepFreeze(value) { if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value; if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return value; for (const child of Object.values(value)) deepFreeze(child); return Object.freeze(value); }
@@ -0,0 +1,22 @@
1
+ import { WORKSPACE_PACKAGE_ROLE } from './recipientV2.packageV1.contract.js';
2
+ import { deepFreeze } from './recipientV2.packageV1.shared.js';
3
+
4
+ export function workspaceCarrierProjection(workspaceParts = [], lineage = null) {
5
+ const workspaces = workspaceParts.map((item) => Object.freeze({
6
+ id: String(item.workspaceId || ''),
7
+ title: String(item.workspaceId || ''),
8
+ slug: String(item.workspaceId || '').replace(/[^a-zA-Z0-9._-]+/g, '-').toLowerCase(),
9
+ qualification: item.targetQualification?.state === 'qualified' ? 'qualified' : 'unresolved'
10
+ }));
11
+ const ready = workspaces.length > 0 && workspaces.every((item) => item.qualification === 'qualified');
12
+ return deepFreeze({
13
+ schema: 'tiinex.portable.handoff-carrier-projection.v1', version: 1,
14
+ status: ready ? 'ready' : 'blocked', mode: 'workspace', lineage,
15
+ workspaces: Object.freeze(workspaces),
16
+ workspace: workspaces[0] || Object.freeze({ id: '', title: '', slug: '', qualification: 'unresolved' }),
17
+ selection: Object.freeze({ policy: 'none', qualifiedRouteCount: 0, implicitRouteId: '', packageRole: WORKSPACE_PACKAGE_ROLE }),
18
+ routes: Object.freeze([]),
19
+ authority: Object.freeze({ semanticAuthority: 'none', filenameAuthority: false, dimensionalParentAuthority: false, routeSelectionAuthority: 'none' }),
20
+ findings: Object.freeze([])
21
+ });
22
+ }
@@ -0,0 +1,40 @@
1
+ export function parseRecipientV2Pointer(markdown = '') {
2
+ const current = sectionText(markdown, 'Current Read');
3
+ const destinations = sectionText(markdown, 'Destinations');
4
+ return Object.freeze({
5
+ role: fieldValue(current, 'Carrier Role'),
6
+ workspaceId: unquoteCode(fieldValue(current, 'Workspace Id')),
7
+ workspacePayload: markdownTarget(fieldValue(current, 'Workspace Payload')),
8
+ handoffWorkspacePath: unquoteCode(fieldValue(current, 'Handoff Workspace Path')),
9
+ routeId: unquoteCode(fieldValue(current, 'Route Id')),
10
+ routeSelection: fieldValue(current, 'Route Selection'),
11
+ selectedRouteId: unquoteCode(fieldValue(current, 'Selected Route Id')),
12
+ candidateRouteCount: Number(unquoteCode(fieldValue(current, 'Candidate Route Count')) || 0),
13
+ carrierDimension: unquoteCode(fieldValue(current, 'Carrier Dimension')),
14
+ parentCarrierDimension: unquoteCode(fieldValue(current, 'Parent Carrier Dimension')),
15
+ carrierCheckpoint: fieldValue(current, 'Carrier Checkpoint'),
16
+ carrierProfile: fieldValue(current, 'Carrier Profile'),
17
+ compatibilityTransport: fieldValue(current, 'Compatibility Transport'),
18
+ endpointRequirementId: unquoteCode(fieldValue(current, 'Endpoint Requirement Id')),
19
+ endpointParty: fieldValue(current, 'Endpoint Party'),
20
+ participantRequirementId: unquoteCode(fieldValue(current, 'Participant Requirement Id')),
21
+ roleLabelHint: fieldValue(current, 'Role Label Hint'),
22
+ roleReference: unquoteCode(fieldValue(current, 'Role Reference')),
23
+ targetCarrierKind: unquoteCode(fieldValue(current, 'Target Carrier Kind')),
24
+ targetPayload: markdownTarget(fieldValue(current, 'Target Payload')),
25
+ targetWorkspaceId: unquoteCode(fieldValue(current, 'Target Workspace Id')),
26
+ targetInnerPath: unquoteCode(fieldValue(current, 'Target Inner Path')),
27
+ targetArchiveEntry: unquoteCode(fieldValue(current, 'Target Archive Entry')),
28
+ destinations: Object.freeze([...String(destinations || '').matchAll(/\[[^\]]*\]\(([^)]+)\)/g)].map((match) => String(match[1] || '')))
29
+ });
30
+ }
31
+
32
+ function sectionText(markdown = '', heading = '') {
33
+ const escaped = escapeRe(heading);
34
+ const match = String(markdown || '').match(new RegExp(`(?:^|\\n)## ${escaped}\\s*\\n([\\s\\S]*?)(?=\\n## |\\n---\\n|$)`));
35
+ return String(match?.[1] || '').trim();
36
+ }
37
+ function fieldValue(section = '', name = '') { const m = String(section || '').match(new RegExp(`^\\s*-\\s+${escapeRe(name)}:\\s*(.+?)\\s*$`, 'mi')); return String(m?.[1] || '').trim(); }
38
+ function unquoteCode(value = '') { const text = String(value || '').trim(); return text.startsWith('`') && text.endsWith('`') ? text.slice(1, -1) : text; }
39
+ function markdownTarget(value = '') { return String(value || '').match(/\[[^\]]*\]\(([^)]+)\)/)?.[1] || String(value || '').trim(); }
40
+ function escapeRe(value = '') { return String(value || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
@@ -0,0 +1,16 @@
1
+ export function selectRecipientRoutes(routes = [], selector = '', findings = []) {
2
+ const qualified = [...routes].filter((route) => String(route.state || '') === 'qualified');
3
+ const requested = String(selector || '').trim();
4
+ if (!requested) return Object.freeze({ selector: '', routes: Object.freeze(qualified) });
5
+ const normalized = normalizeRoutePath(requested);
6
+ const matches = qualified.filter((route) => String(route.id || '') === requested || normalizeRoutePath(route.workspaceRelativePath || '') === normalized || `${String(route.workspaceId || '')}:${normalizeRoutePath(route.workspaceRelativePath || '')}` === requested);
7
+ if (matches.length !== 1) {
8
+ findings.push(Object.freeze({ severity: 'error', code: matches.length > 1 ? 'portable.handoff-v2-surface.route-selector.ambiguous' : 'portable.handoff-v2-surface.route-selector.unresolved', message: 'Recipient-v2 selected transport route must resolve to exactly one qualified Handoff route before the visible surface is generated.', selector: requested, matches: matches.length }));
9
+ return Object.freeze({ selector: requested, routes: Object.freeze([]) });
10
+ }
11
+ return Object.freeze({ selector: requested, routes: Object.freeze(matches) });
12
+ }
13
+
14
+ function normalizeRoutePath(value = '') {
15
+ return String(value || '').trim().replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\/+/, '');
16
+ }
@@ -0,0 +1,20 @@
1
+ import { sha256Hex, utf8Bytes } from '../../../export/package.bytes.js';
2
+
3
+ export function recipientPackageRootPath(workspaces = []) {
4
+ if (workspaces.length === 1) return `001-${safeToken(workspaces[0].workspaceId || 'tiinex')}-handoff-package.trace.md`;
5
+ return '001-tiinex-handoff-package.trace.md';
6
+ }
7
+
8
+ export function recipientEntriesFingerprint(entries = []) {
9
+ const identities = entries.map((entry) => ({ path: String(entry.path || ''), bytes: Number(entry.bytes || 0), sha256: String(entry.sha256 || '') })).sort((a, b) => a.path.localeCompare(b.path));
10
+ return sha256Hex(utf8Bytes(JSON.stringify(sortJson(identities))));
11
+ }
12
+
13
+ function safeToken(value = '') {
14
+ return String(value || '').trim().toLowerCase().normalize('NFKD').replace(/[\u0300-\u036f]/g, '').replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 80) || 'workspace';
15
+ }
16
+ function sortJson(value) {
17
+ if (Array.isArray(value)) return value.map(sortJson);
18
+ if (!value || typeof value !== 'object') return value;
19
+ return Object.fromEntries(Object.keys(value).sort().map((key) => [key, sortJson(value[key])]));
20
+ }