@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,246 @@
1
+ const LAYER_PRECEDENCE = Object.freeze({
2
+ workspace: 500,
3
+ site: 400,
4
+ verse: 300,
5
+ app: 200,
6
+ core: 100,
7
+ other: 0
8
+ });
9
+
10
+ export const COMPANION_RESOLUTION_SCHEMA_ID = 'tiinex.core.companion-resolution.v1';
11
+ export const COMPANION_PROVIDER_SCHEMA_ID = 'tiinex.core.companion-provider.v1';
12
+
13
+ export function defineCompanionProvider(input = {}) {
14
+ const id = text(input.id);
15
+ if (!id) throw new TypeError('Companion provider id is required.');
16
+ const layer = text(input.layer || 'other').toLowerCase();
17
+ const precedence = finite(input.precedence, LAYER_PRECEDENCE[layer] ?? LAYER_PRECEDENCE.other);
18
+ const resources = freeze((Array.isArray(input.resources) ? input.resources : []).map((resource, index) => normalizeResource(resource, { providerId: id, layer, precedence, index })));
19
+ return freeze({
20
+ schema: COMPANION_PROVIDER_SCHEMA_ID,
21
+ id,
22
+ layer,
23
+ precedence,
24
+ resources,
25
+ boundary: text(input.boundary || 'data-only companion provider; provider presence does not create Tiinex semantic authority')
26
+ });
27
+ }
28
+
29
+ export function resolveCompanionResources(input = {}) {
30
+ const query = normalizeQuery(input.query || input);
31
+ const providers = (Array.isArray(input.providers) ? input.providers : []).map((provider) => provider?.schema === COMPANION_PROVIDER_SCHEMA_ID ? provider : defineCompanionProvider(provider));
32
+ const findings = [];
33
+ const candidates = [];
34
+
35
+ for (const provider of providers) {
36
+ for (const resource of provider.resources) {
37
+ if (resource.namespace !== query.namespace || resource.slot !== query.slot) continue;
38
+ const specificity = resourceSpecificity(resource, query);
39
+ if (specificity < 0) continue;
40
+ candidates.push(freeze({ ...resource, specificity }));
41
+ }
42
+ }
43
+
44
+ candidates.sort(compareCandidates);
45
+ const bestSpecificity = candidates[0]?.specificity ?? -1;
46
+ const specificityCandidates = candidates.filter((item) => item.specificity === bestSpecificity);
47
+ const bestPrecedence = specificityCandidates[0]?.providerPrecedence ?? -Infinity;
48
+ const finalists = specificityCandidates.filter((item) => item.providerPrecedence === bestPrecedence);
49
+ const cardinality = query.cardinality || finalists[0]?.cardinality || 'single';
50
+
51
+ let status = 'missing';
52
+ let resources = [];
53
+ if (!candidates.length) {
54
+ findings.push(finding('info', 'companion.resource.missing', 'No registered companion resource matched the qualified query.', query));
55
+ } else if (cardinality === 'multiple') {
56
+ status = 'resolved';
57
+ const groups = new Map();
58
+ for (const candidate of candidates) { const key = candidate.key || candidate.path || candidate.id; const values = groups.get(key) || []; values.push(candidate); groups.set(key, values); }
59
+ for (const [key, values] of [...groups].sort(([a], [b]) => codePoint(a, b))) {
60
+ const first = values[0];
61
+ const tied = stableUnique(values.filter(v => v.specificity === first.specificity && v.providerPrecedence === first.providerPrecedence), resourceIdentity);
62
+ if (tied.length !== 1) { status = 'ambiguous'; findings.push(finding('error', 'companion.collection.key.ambiguous', 'A collection key has conflicting equally ranked resources.', { key })); }
63
+ else resources.push(tied[0]);
64
+ }
65
+ if (status === 'ambiguous') resources = [];
66
+ } else {
67
+ const unique = stableUnique(finalists, resourceIdentity);
68
+ if (unique.length === 1) {
69
+ status = 'resolved';
70
+ resources = unique;
71
+ } else {
72
+ status = 'ambiguous';
73
+ findings.push(finding('error', 'companion.resource.ambiguous', 'More than one same-specificity, same-precedence single-value companion remains. Resolution failed closed.', {
74
+ namespace: query.namespace,
75
+ slot: query.slot,
76
+ candidateCount: unique.length,
77
+ providerIds: unique.map((item) => item.providerId)
78
+ }));
79
+ }
80
+ }
81
+
82
+ const winnerIds = new Set(resources.map(resourceIdentity));
83
+ const shadowed = candidates.filter((item) => !winnerIds.has(resourceIdentity(item)));
84
+ return freeze({
85
+ schema: COMPANION_RESOLUTION_SCHEMA_ID,
86
+ status,
87
+ query,
88
+ resources,
89
+ candidates,
90
+ shadowed,
91
+ findings,
92
+ receipt: {
93
+ specificity: bestSpecificity,
94
+ providerPrecedence: Number.isFinite(bestPrecedence) ? bestPrecedence : null,
95
+ selectedProviders: [...new Set(resources.map((item) => item.providerId))],
96
+ shadowedProviders: [...new Set(shadowed.map((item) => item.providerId))]
97
+ },
98
+ boundary: 'Specificity resolves before provider precedence. Filename order, import order, repository location and display labels never create authority.'
99
+ });
100
+ }
101
+
102
+ export function companionProviderFromWorkspace(workspace = {}, options = {}) {
103
+ const workspaceId = text(workspace.id || workspace.workspaceId || 'workspace');
104
+ const records = Array.isArray(workspace.records) ? workspace.records : [];
105
+ const assets = Array.isArray(workspace.assets) ? workspace.assets : [];
106
+ const resources = [];
107
+ const findings = [];
108
+ const recordsByPath = new Map(records.map((record) => [normPath(record.path || record.id || ''), record]).filter(([path]) => path));
109
+
110
+ for (const asset of assets) {
111
+ const assetPath = normPath(asset.path || asset.id || '');
112
+ if (!assetPath) continue;
113
+ const parsed = parseCompanionFilename(assetPath);
114
+ if (!parsed) continue;
115
+ let ownerArtifactPath = normPath(asset.ownerArtifactPath || '');
116
+ if (!ownerArtifactPath) {
117
+ const siblingCandidates = candidateArtifactPathsForCompanion(assetPath, parsed);
118
+ const matches = siblingCandidates.filter((path) => recordsByPath.has(path));
119
+ if (matches.length === 1) ownerArtifactPath = matches[0];
120
+ else if (matches.length > 1) {
121
+ findings.push(finding('error', 'companion.workspace.owner.ambiguous', 'Artifact-local companion filename matches more than one loaded artifact candidate.', { workspaceId, assetPath, matches }));
122
+ continue;
123
+ }
124
+ }
125
+ if (!ownerArtifactPath) continue;
126
+ if (!recordsByPath.has(ownerArtifactPath)) {
127
+ findings.push(finding('warning', 'companion.workspace.owner.unloaded', 'Companion declares an artifact owner that is not loaded in the Workspace snapshot.', { workspaceId, assetPath, ownerArtifactPath }));
128
+ continue;
129
+ }
130
+ resources.push({
131
+ namespace: parsed.namespace,
132
+ slot: parsed.slot,
133
+ cardinality: parsed.cardinality,
134
+ owner: { kind: 'artifact', workspaceId, artifactPath: ownerArtifactPath },
135
+ path: assetPath,
136
+ mediaType: text(asset.mediaType || asset.type || mimeFromPath(assetPath)),
137
+ sha256: text(asset.sha256 || ''),
138
+ source: freeze({ workspaceId, assetId: text(asset.id || assetPath), sourceMode: text(asset.sourceMode || asset.source?.adapterId || 'workspace') })
139
+ });
140
+ }
141
+ return freeze({ provider: defineCompanionProvider({ id: text(options.id || `workspace:${workspaceId}`), layer: 'workspace', precedence: options.precedence, resources }), findings });
142
+ }
143
+
144
+ export function parseCompanionFilename(path = '') {
145
+ const name = normPath(path).split('/').at(-1) || '';
146
+ const match = name.match(/^(.*)\.([a-z0-9][a-z0-9_-]*)\.([a-z0-9][a-z0-9_-]*)(?:\.(many|multiple))?\.([a-z0-9]+)$/i);
147
+ if (!match) return null;
148
+ // The common form is owner.namespace.slot.ext. Optional cardinality token may be
149
+ // `many`/`multiple`; arbitrary extra tokens are treated as part of the slot so
150
+ // filenames remain forward-compatible without implicit semantics.
151
+ let [, ownerStem, namespace, slot, extra, extension] = match;
152
+ let cardinality = 'single';
153
+ if (extra && ['many', 'multiple'].includes(extra.toLowerCase())) cardinality = 'multiple';
154
+ else if (extra) slot = `${slot}.${extra}`;
155
+ return freeze({ ownerStem, namespace: namespace.toLowerCase(), slot: slot.toLowerCase(), cardinality, extension: extension.toLowerCase() });
156
+ }
157
+
158
+ function normalizeResource(resource = {}, provider = {}) {
159
+ const namespace = text(resource.namespace).toLowerCase();
160
+ const slot = text(resource.slot).toLowerCase();
161
+ if (!namespace || !slot) throw new TypeError('Companion resource namespace and slot are required.');
162
+ const owner = normalizeOwner(resource.owner || {});
163
+ const cardinality = text(resource.cardinality || 'single').toLowerCase() === 'multiple' ? 'multiple' : 'single';
164
+ const path = normPath(resource.path || '');
165
+ if (path.split('/').includes('..') || /^(?:[a-z]:|\/)/i.test(text(resource.path))) throw new TypeError('Companion path must be relative and stay inside its provider.');
166
+ const id = text(resource.id || `${provider.providerId}:${namespace}:${slot}:${ownerIdentity(owner)}:${path || provider.index}`);
167
+ return freeze({
168
+ id,
169
+ key: text(resource.key || ''),
170
+ namespace,
171
+ slot,
172
+ cardinality,
173
+ owner,
174
+ path,
175
+ url: text(resource.url || ''),
176
+ mediaType: text(resource.mediaType || ''),
177
+ sha256: text(resource.sha256 || ''),
178
+ source: resource.source || null,
179
+ providerId: provider.providerId,
180
+ providerLayer: provider.layer,
181
+ providerPrecedence: provider.precedence
182
+ });
183
+ }
184
+
185
+ function normalizeOwner(owner = {}) {
186
+ const kind = text(owner.kind || 'root').toLowerCase();
187
+ if (kind === 'artifact') return freeze({ kind, workspaceId: text(owner.workspaceId), artifactPath: normPath(owner.artifactPath || owner.path || '') });
188
+ if (kind === 'schema') return freeze({ kind, schemaId: text(owner.schemaId || owner.id) });
189
+ if (kind !== 'root') throw new TypeError('Unsupported companion owner kind.');
190
+ return freeze({ kind: 'root', schemaId: text(owner.schemaId || '') });
191
+ }
192
+
193
+ function normalizeQuery(input = {}) {
194
+ const owner = normalizeOwner(input.owner || {});
195
+ return freeze({
196
+ namespace: text(input.namespace).toLowerCase(),
197
+ slot: text(input.slot).toLowerCase(),
198
+ cardinality: text(input.cardinality).toLowerCase() === 'multiple' ? 'multiple' : text(input.cardinality).toLowerCase() === 'single' ? 'single' : '',
199
+ owner,
200
+ schemaLineage: freeze((Array.isArray(input.schemaLineage) ? input.schemaLineage : []).map(text).filter(Boolean))
201
+ });
202
+ }
203
+
204
+ function resourceSpecificity(resource, query) {
205
+ const owner = resource.owner;
206
+ if (owner.kind === 'artifact') {
207
+ return query.owner.kind === 'artifact' && owner.workspaceId === query.owner.workspaceId && owner.artifactPath === query.owner.artifactPath ? 1000 : -1;
208
+ }
209
+ if (owner.kind === 'schema') {
210
+ const schemaId = query.owner.kind === 'schema' ? query.owner.schemaId : query.schemaLineage[0] || '';
211
+ const lineage = query.schemaLineage.length ? query.schemaLineage : schemaId ? [schemaId] : [];
212
+ const index = lineage.indexOf(owner.schemaId);
213
+ return index < 0 ? -1 : 800 - index;
214
+ }
215
+ return 100;
216
+ }
217
+
218
+ function compareCandidates(a, b) {
219
+ return b.specificity - a.specificity || b.providerPrecedence - a.providerPrecedence || codePoint(a.providerId, b.providerId) || codePoint(a.id, b.id);
220
+ }
221
+
222
+ function candidateArtifactPathsForCompanion(assetPath, parsed) {
223
+ const parts = normPath(assetPath).split('/');
224
+ parts.pop();
225
+ const dir = parts.length ? `${parts.join('/')}/` : '';
226
+ return [
227
+ `${dir}${parsed.ownerStem}.trace.md`,
228
+ `${dir}${parsed.ownerStem}.workspace.md`,
229
+ `${dir}${parsed.ownerStem}.md`
230
+ ];
231
+ }
232
+
233
+ function ownerIdentity(owner) {
234
+ if (owner.kind === 'artifact') return `${owner.workspaceId}::${owner.artifactPath}`;
235
+ if (owner.kind === 'schema') return owner.schemaId;
236
+ return 'root';
237
+ }
238
+ function resourceIdentity(item) { return `${item.providerId}|${item.id}|${item.sha256}|${item.path}|${item.url}`; }
239
+ function stableUnique(items, key) { const seen = new Set(); return items.filter((item) => { const value = key(item); if (seen.has(value)) return false; seen.add(value); return true; }); }
240
+ function normPath(value = '') { return text(value).replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\/+|\/+$/g, ''); }
241
+ function mimeFromPath(path) { const ext = normPath(path).split('.').at(-1)?.toLowerCase(); return ({ png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', webp: 'image/webp', svg: 'image/svg+xml', json: 'application/json', md: 'text/markdown' })[ext] || 'application/octet-stream'; }
242
+ function finite(value, fallback) { const number = Number(value); return Number.isFinite(number) ? number : fallback; }
243
+ function text(value) { return String(value ?? '').trim(); }
244
+ function codePoint(a, b) { return a < b ? -1 : a > b ? 1 : 0; }
245
+ function finding(severity, code, message, details = {}) { return freeze({ severity, code, message, details }); }
246
+ function freeze(value) { if (Array.isArray(value)) return Object.freeze(value.map(freeze)); if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value; return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [key, freeze(item)]))); }
@@ -0,0 +1,16 @@
1
+ export { parseArtifactMarkdown, parseContinuityEnvelope, parseBody, parseIntegrity } from '../artifacts/artifact.parse.js';
2
+ export {
3
+ APPLICATION_DATA_SCHEMA_ID,
4
+ projectApplicationData,
5
+ toPlaythingsStoryRecords
6
+ } from './applicationProjection.js';
7
+ export {
8
+ COMPANION_PROVIDER_SCHEMA_ID,
9
+ COMPANION_RESOLUTION_SCHEMA_ID,
10
+ defineCompanionProvider,
11
+ resolveCompanionResources,
12
+ companionProviderFromWorkspace,
13
+ parseCompanionFilename
14
+ } from './companionResources.js';
15
+
16
+ export { projectSchemaAncestry } from './schemaAncestry.js';
@@ -0,0 +1,2 @@
1
+ export * from './index.js';
2
+ export * from '../tooling/portable/index.js';
@@ -0,0 +1,26 @@
1
+ /** Traverses explicit schema declarations supplied by a qualified host/provider.
2
+ * Presence in this array is NOT independent schema-authority qualification. */
3
+ export function projectSchemaAncestry(schemaId, declarations = []) {
4
+ const groups = new Map();
5
+ for (const declaration of declarations) {
6
+ if (!declaration?.id) continue;
7
+ const values = groups.get(declaration.id) || [];
8
+ values.push(declaration); groups.set(declaration.id, values);
9
+ }
10
+ const lineage = [], seen = new Set(); let current = String(schemaId || '');
11
+ const done = (status, reason) => Object.freeze({ status, reason, lineage: Object.freeze([...lineage]), basis: 'explicit-provider-schema-parent-declarations' });
12
+ if (!current) return done('unresolved', 'schema-id-missing');
13
+ while (current) {
14
+ if (seen.has(current)) return done('cycle', 'schema-parent-cycle');
15
+ seen.add(current); lineage.push(current);
16
+ const values = groups.get(current) || [];
17
+ if (!values.length) return done('unresolved', 'schema-parent-not-loaded');
18
+ const parents = new Set(values.map(v => Object.hasOwn(v, 'parentSchemaId') ? v.parentSchemaId : undefined));
19
+ if (parents.size !== 1) return done('ambiguous', 'conflicting-schema-parent-declarations');
20
+ const parent = [...parents][0];
21
+ if (parent === null || parent === '') return done('resolved', 'explicit-schema-root');
22
+ if (typeof parent !== 'string') return done('unresolved', 'schema-parent-not-declared');
23
+ current = parent;
24
+ }
25
+ return done('unresolved', 'schema-parent-not-declared');
26
+ }
@@ -0,0 +1,196 @@
1
+ import { buildPublicationPreflight } from './publication.preflight.js';
2
+ import { isSourceBacked } from '../diagnostics/sourceBoundary.report.js';
3
+ import { projectPackageSourceReference } from '../export/package.sourceReference.js';
4
+ import { sha256Hex, utf8Bytes } from '../export/package.bytes.js';
5
+ import { normalizePublicationDestination, projectExecutedPublicationTarget, publicationDestinationFindings, publicationTargetQualified } from './publication.targetContract.js';
6
+
7
+ export const PUBLICATION_PLAN_SCHEMA_ID = 'tiinex.publication.plan.v1';
8
+ export const PUBLICATION_RESULT_SCHEMA_ID = 'tiinex.publication.result.v1';
9
+ export const PUBLICATION_RECEIPT_SCHEMA_ID = 'tiinex.publication.receipt.v1';
10
+
11
+ export function buildPublicationPlan(workspace = {}, input = {}) {
12
+ const records = Array.isArray(input.records) ? input.records : (Array.isArray(workspace.records) ? workspace.records : []);
13
+ const preflight = input.preflight || buildPublicationPreflight(workspace, { records, assets: input.assets || workspace.assets || [] });
14
+ const record = input.record || findRecord(records, input.recordId || input.path || '');
15
+ const findings = [];
16
+ if (!record) findings.push(finding('error', 'publication.plan.input.missing', 'Publication plan requires one exact local-owned input record.'));
17
+ if (record && isSourceBacked(record.source || {})) findings.push(finding('error', 'publication.plan.input.source-backed', 'Source-backed material is reference-only and cannot become a mutable local publication payload without an explicit derived local draft.', { recordId: record.id || '' }));
18
+ const candidate = record ? (preflight.publishableLocalDrafts || []).find((item) => item.id === record.id || item.path === record.path) : null;
19
+ if (record && !candidate) findings.push(finding('error', 'publication.plan.input.not-preflight-qualified', 'Local input is not qualified by current publication preflight.', { recordId: record.id || '', path: record.path || '' }));
20
+
21
+ const destination = normalizePublicationDestination(input.destination || {});
22
+ const mutationPolicy = String(input.mutationPolicy || '').trim();
23
+ if (!mutationPolicy) findings.push(finding('error', 'publication.plan.mutation-policy.missing', 'Publication plan requires an explicit mutation policy; host execution must not infer create/update/replace behavior.'));
24
+ findings.push(...publicationDestinationFindings(destination, mutationPolicy));
25
+ const markdown = String(record?.markdown || '');
26
+ const payloadBytes = utf8Bytes(markdown);
27
+ const payload = deepFreeze({
28
+ mediaType: 'text/markdown',
29
+ bytes: payloadBytes.byteLength,
30
+ sha256: sha256Hex(payloadBytes),
31
+ representation: 'exact-local-markdown',
32
+ content: markdown
33
+ });
34
+ const localInput = deepFreeze({
35
+ id: String(record?.id || ''),
36
+ title: String(record?.title || ''),
37
+ path: String(record?.path || ''),
38
+ schemaId: String(record?.schemaId || record?.currentSchemaId || ''),
39
+ sourceMode: String(record?.sourceMode || ''),
40
+ ownership: record && !isSourceBacked(record.source || {}) ? 'owned-local' : 'not-owned-local',
41
+ sourceUnchangedGuarantee: true
42
+ });
43
+ const verification = deepFreeze({
44
+ required: true,
45
+ requirement: 'provider-read-after-write-exact-representation',
46
+ expectedPayloadSha256: payload.sha256,
47
+ boundary: 'Host adapter must return exact post-write source identity and verification evidence; a transport success alone is not a durable source binding.'
48
+ });
49
+ const errors = findings.filter((item) => item.severity === 'error').length;
50
+ const status = errors ? 'blocked' : 'ready';
51
+ const identitySeed = {
52
+ localInput: { id: localInput.id, path: localInput.path },
53
+ destination,
54
+ mutationPolicy,
55
+ payload: { bytes: payload.bytes, sha256: payload.sha256 },
56
+ verification: { required: verification.required, requirement: verification.requirement }
57
+ };
58
+ const planSha256 = sha256Hex(utf8Bytes(stableJson(identitySeed)));
59
+ return deepFreeze({
60
+ schema: PUBLICATION_PLAN_SCHEMA_ID,
61
+ planId: `publication-plan:${planSha256.slice(0, 24)}`,
62
+ status,
63
+ boundary: 'Platform-neutral publication plan only. It performs no remote write, credential lookup, UI confirmation, local-source mutation, or automatic provenance assignment.',
64
+ workspaceId: String(workspace.id || ''),
65
+ localInput,
66
+ destination,
67
+ mutationPolicy,
68
+ outboundPayload: payload,
69
+ verification,
70
+ guarantees: [
71
+ 'The local draft identity remains distinct from the publication operation and remote target identity.',
72
+ 'The local input/source state is not mutated by this plan.',
73
+ 'A successful host write without exact post-write verification does not create a durable source binding.'
74
+ ],
75
+ planSha256,
76
+ findings
77
+ });
78
+ }
79
+
80
+ export function buildPublicationResult(plan = {}, execution = {}) {
81
+ const findings = [...(plan.findings || [])];
82
+ if (plan.status !== 'ready') findings.push(finding('error', 'publication.result.plan-not-ready', 'Publication result cannot qualify success from a blocked publication plan.'));
83
+ const executionState = normalizeExecutionState(execution.state || execution.status || '');
84
+ if (!executionState) findings.push(finding('error', 'publication.result.execution-state.invalid', 'Publication result requires explicit success, failure, or partial execution state.'));
85
+ const verificationState = normalizeVerificationState(execution.verification?.status || execution.verificationStatus || '');
86
+ const targetProjection = projectExecutedPublicationTarget(plan, execution);
87
+ const exactTarget = targetProjection.target;
88
+ if (verificationState === 'verified') findings.push(...(targetProjection.findings || []));
89
+ const hostWriteSucceeded = executionState === 'success' || executionState === 'partial';
90
+ if (hostWriteSucceeded && verificationState !== 'verified') findings.push(finding('warning', 'publication.result.verification.incomplete', 'Host write is not durably source-qualified until exact post-write verification succeeds.'));
91
+ if (executionState === 'success' && verificationState !== 'verified') findings.push(finding('error', 'publication.result.success-without-verification', 'Publication success cannot be claimed without required exact post-write verification.'));
92
+ if (verificationState === 'verified' && !publicationTargetQualified(exactTarget)) findings.push(finding('error', 'publication.result.verified-target.incomplete', 'Verification claims success but exact publication target identity is incomplete for the declared target surface.'));
93
+ if (verificationState === 'verified' && !String(execution.verifiedPayloadSha256 || '').trim()) findings.push(finding('error', 'publication.result.payload-verification.missing', 'Exact verification requires the verified remote payload SHA-256; target existence alone is insufficient.'));
94
+ if (verificationState === 'verified' && execution.verifiedPayloadSha256 && execution.verifiedPayloadSha256 !== plan.outboundPayload?.sha256) findings.push(finding('error', 'publication.result.payload-verification.mismatch', 'Verified remote payload digest differs from the exact planned outbound payload.'));
95
+ const verificationEvidence = deepFreeze({
96
+ source: 'supplied-host-observation',
97
+ method: String(execution.verification?.method || execution.verificationMethod || (verificationState === 'verified' ? 'exact-payload-sha256-observation' : '')).trim(),
98
+ observedAt: String(execution.verification?.observedAt || execution.verifiedAt || execution.observedAt || '').trim(),
99
+ observedTarget: exactTarget,
100
+ payloadSha256: String(execution.verifiedPayloadSha256 || '').trim(),
101
+ providerReceiptId: String(execution.providerReceiptId || exactTarget?.providerReceiptId || '').trim(),
102
+ note: String(execution.verification?.note || execution.verificationNote || '').trim()
103
+ });
104
+
105
+ const errors = findings.filter((item) => item.severity === 'error').length;
106
+ const warnings = findings.filter((item) => item.severity === 'warning').length;
107
+ const qualifiedSuccess = !errors && executionState === 'success' && verificationState === 'verified' && publicationTargetQualified(exactTarget);
108
+ const status = qualifiedSuccess ? 'success' : (executionState === 'failure' || errors ? 'failure' : 'partial');
109
+ const sourceBinding = qualifiedSuccess ? deepFreeze({
110
+ schema: 'tiinex.publication.source-binding.v1',
111
+ localInputId: String(plan.localInput?.id || ''),
112
+ publicationPlanId: String(plan.planId || ''),
113
+ remoteTarget: exactTarget,
114
+ payloadSha256: String(plan.outboundPayload?.sha256 || ''),
115
+ targetKind: String(exactTarget?.targetKind || ''),
116
+ mutability: String(exactTarget?.mutability || ''),
117
+ verificationEvidence,
118
+ verified: true,
119
+ boundary: 'Post-publication source binding records the new exact remote representation without mutating or re-identifying the local draft.'
120
+ }) : null;
121
+ const resultIdentity = {
122
+ planId: plan.planId || '',
123
+ status,
124
+ executionState,
125
+ verificationState,
126
+ remoteTarget: exactTarget,
127
+ payloadSha256: plan.outboundPayload?.sha256 || ''
128
+ };
129
+ const resultSha256 = sha256Hex(utf8Bytes(stableJson(resultIdentity)));
130
+ const receipt = deepFreeze({
131
+ schema: PUBLICATION_RECEIPT_SCHEMA_ID,
132
+ receiptId: `publication-receipt:${resultSha256.slice(0, 24)}`,
133
+ planId: String(plan.planId || ''),
134
+ planSha256: String(plan.planSha256 || ''),
135
+ status,
136
+ executionState,
137
+ verificationState,
138
+ localInputId: String(plan.localInput?.id || ''),
139
+ inputSourceUnchanged: true,
140
+ outboundPayloadSha256: String(plan.outboundPayload?.sha256 || ''),
141
+ verifiedPayloadSha256: String(execution.verifiedPayloadSha256 || ''),
142
+ verificationEvidence,
143
+ remoteTarget: exactTarget,
144
+ sourceBinding,
145
+ remoteWritePerformed: hostWriteSucceeded,
146
+ boundary: 'Receipt describes supplied host execution evidence only. This shared contract does not perform the host write and does not turn the local draft into the remote source artifact.'
147
+ });
148
+
149
+ return deepFreeze({
150
+ schema: PUBLICATION_RESULT_SCHEMA_ID,
151
+ resultId: `publication-result:${resultSha256.slice(0, 24)}`,
152
+ status,
153
+ boundary: 'Platform-neutral publication result over explicitly supplied adapter execution evidence; no remote execution occurs in this module.',
154
+ planId: String(plan.planId || ''),
155
+ executionState,
156
+ verification: {
157
+ required: Boolean(plan.verification?.required),
158
+ status: verificationState || 'not-run',
159
+ expectedPayloadSha256: String(plan.outboundPayload?.sha256 || ''),
160
+ verifiedPayloadSha256: String(execution.verifiedPayloadSha256 || ''),
161
+ evidence: verificationEvidence
162
+ },
163
+ localInput: plan.localInput || null,
164
+ remoteTarget: exactTarget,
165
+ sourceBinding,
166
+ receipt,
167
+ counts: { errors, warnings, findings: findings.length },
168
+ findings
169
+ });
170
+ }
171
+
172
+ function findRecord(records = [], key = '') {
173
+ const clean = String(key || '').trim();
174
+ return records.find((record) => record === key || String(record.id || '') === clean || String(record.path || '') === clean) || null;
175
+ }
176
+ function normalizeExecutionState(value = '') {
177
+ const clean = String(value || '').trim().toLowerCase();
178
+ return ['success', 'failure', 'partial'].includes(clean) ? clean : '';
179
+ }
180
+ function normalizeVerificationState(value = '') {
181
+ const clean = String(value || '').trim().toLowerCase();
182
+ return ['verified', 'failed', 'not-run', 'unavailable'].includes(clean) ? clean : '';
183
+ }
184
+ function stableJson(value) { return JSON.stringify(sortJson(value)); }
185
+ function sortJson(value) {
186
+ if (Array.isArray(value)) return value.map(sortJson);
187
+ if (!value || typeof value !== 'object') return value;
188
+ return Object.fromEntries(Object.keys(value).sort().map((key) => [key, sortJson(value[key])]));
189
+ }
190
+ function finding(severity, code, message, extra = {}) { return Object.freeze({ severity, code, message, ...extra }); }
191
+ function deepFreeze(value) {
192
+ if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value;
193
+ if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return value;
194
+ for (const child of Object.values(value)) deepFreeze(child);
195
+ return Object.freeze(value);
196
+ }
@@ -0,0 +1,159 @@
1
+ import { runAudit } from '../audit/audit.run.js';
2
+ import { buildSourceBoundaryReport, isSourceBacked } from '../diagnostics/sourceBoundary.report.js';
3
+ import { projectPackageSourceReference } from '../export/package.sourceReference.js';
4
+
5
+ export const PUBLICATION_PREFLIGHT_SCHEMA_ID = 'tiinex.publication.preflight.v1';
6
+
7
+ export function buildPublicationPreflight(workspace = {}, input = {}) {
8
+ const records = Array.isArray(input.records) ? input.records : (Array.isArray(workspace.records) ? workspace.records : []);
9
+ const assets = Array.isArray(input.assets) ? input.assets : (Array.isArray(workspace.assets) ? workspace.assets : []);
10
+ const workspaceCandidates = Array.isArray(input.workspaceCandidates) ? input.workspaceCandidates : (Array.isArray(workspace.workspaceMergeCandidates) ? workspace.workspaceMergeCandidates : []);
11
+ const boundary = buildSourceBoundaryReport(workspace, { records, assets });
12
+ const findings = [...(boundary.findings || []).map((finding) => Object.assign({ source: 'source-boundary' }, finding))];
13
+ const publishable = [];
14
+ const blockedRecords = [];
15
+ const sourceReferences = [];
16
+
17
+ for (const record of records) {
18
+ const sourceBacked = isSourceBacked(record.source);
19
+ if (sourceBacked) {
20
+ sourceReferences.push(sourceReferenceForRecord(record, findings));
21
+ continue;
22
+ }
23
+ const assessment = assessLocalPublishCandidate(record);
24
+ if (assessment.publishable) publishable.push(assessment.record);
25
+ else blockedRecords.push(assessment.record);
26
+ findings.push(...assessment.findings);
27
+ }
28
+
29
+ for (const asset of assets) assessAssetForPublication(asset, findings);
30
+ for (const candidate of workspaceCandidates) {
31
+ findings.push(finding('info', 'publication.workspace-candidate.reference-only', 'Workspace candidate requires explicit Open/Merge before publication; it is not treated as a leaf.', { path: candidate.path || '', workspaceCandidateId: candidate.id || '' }));
32
+ }
33
+
34
+ if (!publishable.length) {
35
+ findings.push(finding('warning', 'publication.no-local-draft-candidates', 'No local draft leaves are currently ready for publication. Source-backed material remains reference-only.', { workspaceId: workspace.id || '' }));
36
+ }
37
+
38
+ const errors = findings.filter((item) => item.severity === 'error').length;
39
+ const warnings = findings.filter((item) => item.severity === 'warning').length;
40
+ const status = errors ? 'blocked' : warnings ? 'degraded' : 'ready';
41
+
42
+ return Object.freeze({
43
+ schema: PUBLICATION_PREFLIGHT_SCHEMA_ID,
44
+ workspaceId: workspace.id || '',
45
+ title: `Publication preflight · ${workspace.title || workspace.name || 'workspace'}`,
46
+ status,
47
+ boundary: 'Preflight only. No commit, issue, upload, or remote mutation is performed; local drafts stay local until an explicit publication action exists.',
48
+ counts: Object.freeze({
49
+ records: records.length,
50
+ publishableLocalDrafts: publishable.length,
51
+ blockedLocalDrafts: blockedRecords.length,
52
+ sourceReferences: sourceReferences.length,
53
+ assets: assets.length,
54
+ workspaceCandidates: workspaceCandidates.length,
55
+ errors,
56
+ warnings,
57
+ findings: findings.length
58
+ }),
59
+ publishableLocalDrafts: Object.freeze(publishable),
60
+ blockedLocalDrafts: Object.freeze(blockedRecords),
61
+ sourceReferences: Object.freeze(sourceReferences),
62
+ sourceBoundary: boundary,
63
+ findings: Object.freeze(findings)
64
+ });
65
+ }
66
+
67
+ function assessLocalPublishCandidate(record = {}) {
68
+ const findings = [];
69
+ const id = record.id || record.path || record.title || 'record';
70
+ const markdown = String(record.markdown || '').trim();
71
+ if (!markdown) {
72
+ findings.push(finding('error', 'publication.local-record.no-markdown', 'Local draft has no Markdown body to publish.', { recordId: id, path: record.path || '' }));
73
+ return { publishable: false, record: candidateSummary(record, 'blocked', 'no-markdown'), findings };
74
+ }
75
+ let audit;
76
+ try {
77
+ audit = runAudit({ markdown });
78
+ } catch (error) {
79
+ findings.push(finding('error', 'publication.local-record.audit-exception', error?.message || 'Local draft audit failed.', { recordId: id, path: record.path || '' }));
80
+ return { publishable: false, record: candidateSummary(record, 'blocked', 'audit-exception'), findings };
81
+ }
82
+ const missing = requiredEnvelopeFields(markdown);
83
+ for (const field of missing) {
84
+ findings.push(finding('error', `publication.local-record.missing-${field.code}`, `Local draft is missing ${field.label}.`, { recordId: id, path: record.path || '' }));
85
+ }
86
+ const auditErrors = Number(audit.summary?.error || 0);
87
+ const auditWarnings = Number(audit.summary?.warning || 0);
88
+ // v477: semantic contract validity is disclosed but is not itself publication/export readiness.
89
+ // Publication may preserve/re-home readable local bytes even when reopened semantic validation is incomplete.
90
+ // Envelope/readability failures remain blocking through the explicit publication checks above.
91
+ if (auditErrors) {
92
+ findings.push(finding('info', 'publication.local-record.semantic-contract-invalid', `Local draft currently has ${auditErrors} semantic/audit error${auditErrors === 1 ? '' : 's'}; publication readiness is assessed separately and does not upgrade contract validity.`, { recordId: id, path: record.path || '' }));
93
+ } else if (auditWarnings) {
94
+ findings.push(finding('info', 'publication.local-record.semantic-contract-degraded', `Local draft currently has ${auditWarnings} semantic/audit warning${auditWarnings === 1 ? '' : 's'}; publication readiness is assessed separately.`, { recordId: id, path: record.path || '' }));
95
+ }
96
+ const publishable = !missing.length;
97
+ return {
98
+ publishable,
99
+ record: candidateSummary(record, publishable ? 'ready' : 'blocked', publishable ? 'schema-envelope-ready' : 'audit-or-envelope-failed', audit),
100
+ findings
101
+ };
102
+ }
103
+
104
+ function requiredEnvelopeFields(markdown = '') {
105
+ const text = String(markdown || '');
106
+ const fields = [
107
+ ['envelope-schema', 'Envelope Schema', /Envelope Schema\s*:/i],
108
+ ['current-schema', 'Current Schema', /Current Schema\s*:/i],
109
+ ['current-created-at', 'Current Created At', /-\s*Current[\s\S]*?Created At\s*:/i],
110
+ ['continuity-integrity', 'Continuity Integrity', /Continuity Integrity/i]
111
+ ];
112
+ return fields.filter(([, , pattern]) => !pattern.test(text)).map(([code, label]) => ({ code, label }));
113
+ }
114
+
115
+ function assessAssetForPublication(asset = {}, findings = []) {
116
+ if (asset.previewState === 'omitted-large' || asset.cacheState === 'preview-truncated-for-session-cache') {
117
+ findings.push(finding('warning', 'publication.asset.metadata-only', 'Asset content/preview is not fully available in session cache; package/export must mark it unavailable or require source file selection.', { assetId: asset.id || asset.path || '', path: asset.path || '' }));
118
+ }
119
+ }
120
+
121
+ function sourceReferenceForRecord(record = {}, findings = []) {
122
+ const target = projectPackageSourceReference(record);
123
+ const id = record.id || record.path || record.title || 'record';
124
+ if (target.adapterId === 'github') {
125
+ if (!target.repo) findings.push(finding('error', 'publication.source-reference.repo-missing', 'GitHub source reference is missing repo.', { recordId: id, path: target.path || '' }));
126
+ if (!target.materializedCommit) findings.push(finding('warning', 'publication.source-reference.ref-unpinned', 'GitHub source reference has no immutable materialized commit; re-ingest must preserve it as degraded even when a branch/tag ref exists.', { recordId: id, path: target.path || '', repo: target.repo || '', ref: target.configuredRef || '' }));
127
+ if (!target.path && !target.inputTarget) findings.push(finding('error', 'publication.source-reference.path-missing', 'GitHub source reference is missing exact repo-file or issue/comment target identity.', { recordId: id, repo: target.repo || '' }));
128
+ } else if (!target.inputTarget) {
129
+ findings.push(finding('warning', 'publication.source-reference.target-degraded', 'External source reference has no exact input target and remains degraded.', { recordId: id, path: target.path || '' }));
130
+ }
131
+ return Object.freeze({
132
+ id,
133
+ title: record.title || 'Source-backed artifact',
134
+ path: target.path || String(record.path || ''),
135
+ adapterId: target.adapterId,
136
+ repo: target.repo,
137
+ ref: target.ref,
138
+ status: target.status,
139
+ target,
140
+ writePolicy: 'reference-only; do not publish over source-backed input without explicit derived local draft'
141
+ });
142
+ }
143
+
144
+ function candidateSummary(record = {}, status = 'unknown', reason = '', audit = null) {
145
+ return Object.freeze({
146
+ id: record.id || record.path || record.title || '',
147
+ title: record.title || 'Untitled artifact',
148
+ path: record.path || '',
149
+ status,
150
+ reason,
151
+ schemaId: audit?.artifact?.schemaId || record.schemaId || record.currentSchemaId || '',
152
+ auditStatus: audit?.status || '',
153
+ sourceMode: record.sourceMode || ''
154
+ });
155
+ }
156
+
157
+ function finding(severity, code, message, extra = {}) {
158
+ return Object.freeze(Object.assign({ severity, code, message }, extra));
159
+ }