@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,398 @@
1
+ import { resolveLineage } from '../../../lineage/lineage.resolve.js';
2
+ import { normalizePortableInput } from '../input/portable.input.js';
3
+ import { portableFinding, summarizePortableFindings } from '../findings.js';
4
+ import { renderDot, renderMermaid, renderTextMap } from './lineage.print.render.js';
5
+ import { compactNode, compareEdges, compareIds, compareLatest, compareNodeOrder, hasExplicitMetadata, normalizeList, positiveInteger, slugFromPath, truncate } from './lineage.print.utils.js';
6
+
7
+ export const PORTABLE_LINEAGE_PRINT_SCHEMA_ID = 'tiinex.portable.lineage-print.v1';
8
+ export const PORTABLE_LINEAGE_PRINT_REQUEST_SCHEMA_ID = 'tiinex.portable.lineage-print.request.v1';
9
+
10
+ const SUPPORTED_SCOPES = Object.freeze(['all', 'leaves', 'latest-leaves', 'node-ancestors', 'node-neighborhood', 'segment', 'export-scope']);
11
+ const BOUNDARY = Object.freeze({
12
+ projectionOnly: true,
13
+ sourceMutation: false,
14
+ stateMutation: false,
15
+ remoteFetch: false,
16
+ packageMutation: false,
17
+ loadedOnly: true,
18
+ rawMarkdownIncluded: false,
19
+ notSourceTruth: true
20
+ });
21
+
22
+ export function printPortableLineage(input = {}, options = {}) {
23
+ const scope = normalizeScope(input.scope || options.scope || 'all');
24
+ if (!SUPPORTED_SCOPES.includes(scope)) {
25
+ const findings = [portableFinding('error', 'lineage-print.scope.unsupported', 'Lineage print scope is not supported.', { scope, supportedScopes: SUPPORTED_SCOPES })];
26
+ return projectionResult({ scope, findings, status: 'blocked' });
27
+ }
28
+
29
+ const material = normalizePortableInput(input.materials || input);
30
+ const manifest = parseManifest(input);
31
+ const resolved = resolveLineage(material.records || [], { depth: 'portable-lineage-print' });
32
+ const model = buildProjectionModel(material.records || [], resolved, manifest);
33
+ const selection = selectScope(model, {
34
+ scope,
35
+ focusId: input.focusArtifactId || input.focusId || input.focus || options.focusId || options.startId || '',
36
+ fromId: input.fromArtifactId || input.fromId || input.from || '',
37
+ toId: input.toArtifactId || input.toId || input.to || '',
38
+ artifactIds: normalizeList(input.artifactIds || input.artifacts || options.artifactIds),
39
+ latestLimit: positiveInteger(input.latestLimit || input.limit || options.latestLimit, 5)
40
+ });
41
+ const graph = buildScopedGraph(model, selection, scope);
42
+ const findings = [
43
+ ...(material.findings || []),
44
+ ...normalizeLineageFindings(resolved.findings || []),
45
+ ...(selection.findings || []),
46
+ ...graph.findings,
47
+ ...diagnosticFindings(model, graph, manifest)
48
+ ];
49
+ const allFindings = dedupeByCodeRef(findings);
50
+ const outputFormats = new Set(normalizeList(input.outputFormats || input.formats || options.outputFormats));
51
+ const includeMermaid = outputFormats.has('mermaid') || outputFormats.has('mmd');
52
+ const includeDot = outputFormats.has('dot');
53
+ const textMap = renderTextMap(model, graph, scope, allFindings, manifest);
54
+ return projectionResult({
55
+ scope,
56
+ status: allFindings.some((finding) => finding.severity === 'error') ? 'partial' : 'ready',
57
+ material,
58
+ model,
59
+ graph,
60
+ textMap,
61
+ findings: allFindings,
62
+ exportPreview: buildExportPreview(model, graph, scope, normalizeList(input.artifactIds || input.artifacts || options.artifactIds)),
63
+ manifestSummary: manifestSummary(manifest),
64
+ mermaid: includeMermaid ? renderMermaid(graph) : undefined,
65
+ dot: includeDot ? renderDot(graph) : undefined
66
+ });
67
+ }
68
+
69
+ function projectionResult({ scope = 'all', status = 'ready', material = {}, model = emptyModel(), graph = emptyGraph(), textMap = '', findings = [], exportPreview = null, manifestSummary: manifest = null, mermaid, dot }) {
70
+ const findingSummary = summarizePortableFindings(findings);
71
+ return Object.freeze({
72
+ schema: PORTABLE_LINEAGE_PRINT_SCHEMA_ID,
73
+ status,
74
+ scope,
75
+ stats: Object.freeze({
76
+ artifacts: model.records.length,
77
+ selectedArtifacts: graph.nodes.filter((node) => node.kind === 'artifact' && node.status === 'included').length,
78
+ roots: model.roots.length,
79
+ leaves: model.leaves.length,
80
+ parentEdges: model.parentEdges.length,
81
+ missingParentEdges: model.missingParentEdges.length,
82
+ hiddenEdges: graph.edges.filter((edge) => edge.status === 'hidden-intermediate' || edge.status === 'known-but-excluded').length,
83
+ liveProcessedTurns: model.live.processedTurnCount,
84
+ liveArtifactChangeTurns: model.live.artifactChangeTurnCount
85
+ }),
86
+ graph: Object.freeze({ nodes: Object.freeze(graph.nodes), edges: Object.freeze(graph.edges) }),
87
+ textMap,
88
+ latestLeaves: Object.freeze(model.latestLeaves.map((id) => compactNode(model.nodeById.get(id))).filter(Boolean)),
89
+ roots: Object.freeze(model.roots.map((id) => compactNode(model.nodeById.get(id))).filter(Boolean)),
90
+ leaves: Object.freeze(model.leaves.map((id) => compactNode(model.nodeById.get(id))).filter(Boolean)),
91
+ exportPreview: exportPreview ? Object.freeze(exportPreview) : undefined,
92
+ manifestSummary: manifest ? Object.freeze(manifest) : undefined,
93
+ ...(mermaid ? { mermaid } : {}),
94
+ ...(dot ? { dot } : {}),
95
+ findings: Object.freeze(findings),
96
+ findingSummary,
97
+ boundary: BOUNDARY
98
+ });
99
+ }
100
+
101
+ function buildProjectionModel(records = [], resolved = {}, manifest = {}) {
102
+ const nodes = (resolved.nodes || []).map((node, index) => normalizeNode(node, records[index] || node.record || {}, index));
103
+ const nodeById = new Map(nodes.map((node) => [node.id, node]));
104
+ const edges = (resolved.edges || []).map(normalizeEdge).sort(compareEdges);
105
+ const parentEdges = edges.filter((edge) => edge.relation === 'parent' && edge.from && edge.to && edge.status !== 'missing');
106
+ const missingParentEdges = edges.filter((edge) => edge.relation === 'parent' && (!edge.from || edge.status === 'missing'));
107
+ const parentByChild = new Map();
108
+ const childrenByParent = new Map();
109
+ for (const edge of parentEdges) {
110
+ parentByChild.set(edge.to, edge.from);
111
+ if (!childrenByParent.has(edge.from)) childrenByParent.set(edge.from, []);
112
+ childrenByParent.get(edge.from).push(edge.to);
113
+ }
114
+ for (const children of childrenByParent.values()) children.sort(compareIds);
115
+ const roots = nodes.filter((node) => !parentByChild.has(node.id)).map((node) => node.id).sort(compareNodeOrder(nodeById));
116
+ const leaves = nodes.filter((node) => !(childrenByParent.get(node.id) || []).length).map((node) => node.id).sort(compareNodeOrder(nodeById));
117
+ const live = liveStats(manifest, nodes);
118
+ const latestLeaves = [...leaves].sort(compareLatest(nodeById, live));
119
+ return Object.freeze({ records, nodes, nodeById, edges, parentEdges, missingParentEdges, parentByChild, childrenByParent, roots, leaves, latestLeaves, live });
120
+ }
121
+
122
+ function normalizeNode(node = {}, record = {}, index = 0) {
123
+ const id = String(node.id || record.id || record.path || `lineage-node-${index + 1}`);
124
+ const slug = slugFromPath(record.path || node.path || id);
125
+ const liveTouch = { latestTurnSequence: 0, latestObservedAt: '' };
126
+ return {
127
+ id,
128
+ slug,
129
+ kind: 'artifact',
130
+ status: 'included',
131
+ title: String(node.title || record.title || record.path || id),
132
+ path: String(node.path || record.path || ''),
133
+ schemaId: String(node.schemaId || record.schemaId || record.kind || ''),
134
+ sourceMode: String(node.sourceMode || record.sourceMode || ''),
135
+ boundary: String(node.boundary || record.boundary || record.source?.boundary || 'Portable local material; no GitHub provenance inferred.'),
136
+ summary: truncate(String(record.summary || node.record?.summary || ''), 220),
137
+ currentCreatedAt: String(record.currentCreatedAt || ''),
138
+ lifecycleStatus: String(record.lifecycleStatus || ''),
139
+ hasContinuityContext: Boolean(record.hasContinuityContext || node.hasContinuityContext),
140
+ hasIntegrity: Boolean(record.hasIntegrity || node.hasIntegrity),
141
+ hasAuthorshipMetadata: hasExplicitMetadata(record.markdown, ['author', 'authors', 'contributor', 'contributors', 'authorship']),
142
+ hasReductionMetadata: hasExplicitMetadata(record.markdown, ['reduction', 'reducer', 'reduced from', 'selection rule', 'known losses']),
143
+ hasSourceSpanMetadata: hasExplicitMetadata(record.markdown, ['source span', 'source-span', 'source range', 'covers turns', 'source turns']),
144
+ liveTouch
145
+ };
146
+ }
147
+
148
+ function normalizeEdge(edge = {}) {
149
+ return Object.freeze({
150
+ id: String(edge.id || `${edge.kind || 'edge'}:${edge.from || 'missing'}->${edge.to || 'missing'}`),
151
+ from: String(edge.from || ''),
152
+ to: String(edge.to || ''),
153
+ relation: String(edge.kind || edge.relation || 'parent'),
154
+ status: edge.status === 'missing' ? 'missing' : String(edge.status || 'included'),
155
+ target: String(edge.target || ''),
156
+ source: 'declared-lineage',
157
+ label: String(edge.label || edge.kind || 'edge')
158
+ });
159
+ }
160
+
161
+ function selectScope(model, request = {}) {
162
+ const findings = [];
163
+ let selected = new Set();
164
+ const artifactIds = resolveArtifactIds(model, request.artifactIds || []);
165
+ if (request.scope === 'all') selected = new Set(model.nodes.map((node) => node.id));
166
+ else if (request.scope === 'export-scope') selected = new Set(artifactIds.length ? artifactIds : model.nodes.map((node) => node.id));
167
+ else if (request.scope === 'leaves') selected = idsWithAncestors(model, model.leaves);
168
+ else if (request.scope === 'latest-leaves') selected = idsWithAncestors(model, model.latestLeaves.slice(0, request.latestLimit || 5));
169
+ else if (request.scope === 'node-ancestors') {
170
+ const focus = resolveArtifactId(model, request.focusId);
171
+ if (!focus) findings.push(portableFinding('error', 'lineage-print.focus-missing', 'node-ancestors scope requires a loaded focus artifact id/path/slug.', { ref: request.focusId || '' }));
172
+ selected = focus ? idsWithAncestors(model, [focus]) : new Set();
173
+ } else if (request.scope === 'node-neighborhood') {
174
+ const focus = resolveArtifactId(model, request.focusId);
175
+ if (!focus) findings.push(portableFinding('error', 'lineage-print.focus-missing', 'node-neighborhood scope requires a loaded focus artifact id/path/slug.', { ref: request.focusId || '' }));
176
+ selected = focus ? neighborhoodIds(model, focus) : new Set();
177
+ } else if (request.scope === 'segment') {
178
+ const from = resolveArtifactId(model, request.fromId);
179
+ const to = resolveArtifactId(model, request.toId);
180
+ if (!from || !to) findings.push(portableFinding('error', 'lineage-print.segment-endpoint-missing', 'segment scope requires loaded from/to artifact ids, paths, or slugs.', { from: request.fromId || '', to: request.toId || '' }));
181
+ selected = from && to ? segmentIds(model, from, to, findings) : new Set();
182
+ }
183
+ return Object.freeze({ ids: selected, findings });
184
+ }
185
+
186
+ function buildScopedGraph(model, selection, scope = 'all') {
187
+ const selected = selection.ids || new Set();
188
+ const findings = [];
189
+ const nodes = [...selected].map((id) => model.nodeById.get(id)).filter(Boolean).sort(compareNodeOrder(model.nodeById)).map(compactNode);
190
+ const edgeKeys = new Set();
191
+ const edges = [];
192
+ function addEdge(edge) {
193
+ const key = [edge.relation, edge.from || '', edge.to || '', edge.status || '', edge.hiddenCount || 0].join(':');
194
+ if (edgeKeys.has(key)) return;
195
+ edgeKeys.add(key);
196
+ edges.push(Object.freeze(edge));
197
+ }
198
+ for (const edge of model.parentEdges) {
199
+ if (selected.has(edge.from) && selected.has(edge.to)) addEdge({ ...edge, status: 'included' });
200
+ }
201
+ for (const id of selected) {
202
+ const hidden = hiddenParentPathToSelectedAncestor(model, id, selected);
203
+ if (hidden.hiddenCount > 0 && hidden.ancestorId) {
204
+ addEdge({
205
+ id: `parent-path:${hidden.ancestorId}->${id}`,
206
+ from: hidden.ancestorId,
207
+ to: id,
208
+ relation: 'parent-path',
209
+ status: 'hidden-intermediate',
210
+ hiddenCount: hidden.hiddenCount,
211
+ hiddenIds: Object.freeze(hidden.hiddenIds),
212
+ reason: 'selection-scope',
213
+ source: 'declared-lineage-selection'
214
+ });
215
+ findings.push(portableFinding('info', 'lineage-print.hidden-intermediate', 'Projection hides one or more loaded intermediate lineage nodes; no direct parent edge is implied.', { nodeId: id, ancestorId: hidden.ancestorId, hiddenCount: hidden.hiddenCount, scope }));
216
+ } else if (hidden.hiddenCount > 0) {
217
+ findings.push(portableFinding('info', 'lineage-print.hidden-by-scope', 'Projection omits a loaded parent because it is outside the selected scope.', { nodeId: id, hiddenCount: hidden.hiddenCount, scope }));
218
+ }
219
+ }
220
+ for (const edge of model.missingParentEdges) {
221
+ if (!selected.has(edge.to)) continue;
222
+ addEdge({ ...edge, from: null, status: 'missing-parent', reason: 'declared-parent-not-loaded' });
223
+ findings.push(portableFinding('warning', 'lineage-print.parent.missing', 'A selected artifact declares a parent that is not loaded.', { nodeId: edge.to, target: edge.target }));
224
+ }
225
+ return Object.freeze({ nodes: Object.freeze(nodes), edges: Object.freeze(edges.sort(compareEdges)), findings: Object.freeze(findings) });
226
+ }
227
+
228
+ function diagnosticFindings(model, graph, manifest = {}) {
229
+ const findings = [];
230
+ const live = model.live;
231
+ if (live.processedTurnCount >= 3 && live.artifactChangeTurnCount >= 2 && model.nodes.length <= 1 && model.parentEdges.length === 0) {
232
+ findings.push(portableFinding('warning', 'lineage-print.overcompression.possible', 'Many live turns changed artifacts, but the loaded export contains one or fewer artifacts and no child lineage.', {
233
+ processedTurnCount: live.processedTurnCount,
234
+ artifactChangeTurnCount: live.artifactChangeTurnCount,
235
+ artifactCount: model.nodes.length,
236
+ parentEdges: model.parentEdges.length
237
+ }));
238
+ if (!model.nodes.some((node) => node.hasReductionMetadata)) findings.push(portableFinding('info', 'lineage-print.reduction.capability-missing', 'Compression risk is present, but no explicit reduction metadata/capability is visible in the loaded artifacts.'));
239
+ if (!model.nodes.some((node) => node.hasSourceSpanMetadata)) findings.push(portableFinding('warning', 'lineage-print.source-span.metadata-missing', 'Compression risk is present, but no explicit source-span metadata is visible in the loaded artifacts.'));
240
+ }
241
+ if (model.nodes.length && !model.nodes.some((node) => node.hasAuthorshipMetadata)) findings.push(portableFinding('info', 'lineage-print.authorship.metadata-missing', 'No explicit authorship/contributor metadata was found in loaded artifact envelopes or body fields.'));
242
+ if (manifest?.liveOperations?.boundary?.rawMarkdownIncluded === true) findings.push(portableFinding('warning', 'lineage-print.boundary.raw-markdown-reported', 'Manifest reports raw Markdown was included in live-operation boundary; projection output still omits raw Markdown.'));
243
+ return findings;
244
+ }
245
+
246
+ function buildExportPreview(model, graph, scope, requestedIds = []) {
247
+ const selected = graph.nodes.filter((node) => node.kind === 'artifact' && node.status === 'included');
248
+ const requested = resolveArtifactIds(model, requestedIds);
249
+ return Object.freeze({
250
+ schema: 'tiinex.portable.lineage-print.export-preview.v1',
251
+ mode: scope === 'export-scope' ? 'selected-export-scope' : 'loaded-material-summary',
252
+ requestedArtifactIds: Object.freeze(requested),
253
+ selectedArtifactIds: Object.freeze(selected.map((node) => node.id)),
254
+ selectedArtifactCount: selected.length,
255
+ loadedArtifactCount: model.nodes.length,
256
+ packageMutation: false,
257
+ exportReceiptCreated: false,
258
+ rawMarkdownIncluded: false,
259
+ obviousBlockers: Object.freeze(selected.length ? [] : ['no-selected-artifacts'])
260
+ });
261
+ }
262
+
263
+ function manifestSummary(manifest = {}) {
264
+ if (!manifest || !Object.keys(manifest).length) return null;
265
+ const live = liveStats(manifest, []);
266
+ return Object.freeze({
267
+ schema: 'tiinex.portable.lineage-print.manifest-summary.v1',
268
+ hasManifest: true,
269
+ liveOperations: Object.freeze({
270
+ processedTurnCount: live.processedTurnCount,
271
+ preparedTurnCount: live.preparedTurnCount,
272
+ artifactChangeTurnCount: live.artifactChangeTurnCount,
273
+ noArtifactChangeTurnCount: live.noArtifactChangeTurnCount,
274
+ latestTurnSequence: live.latestTurnSequence,
275
+ latestEventSequence: live.latestEventSequence,
276
+ providerInterleaving: manifest.liveOperations?.qualification?.providerInterleaving || manifest.liveOperations?.boundary?.providerInterleavingQualification || ''
277
+ }),
278
+ boundary: manifest.boundary || null,
279
+ lineage: manifest.lineage || null
280
+ });
281
+ }
282
+
283
+ function liveStats(manifest = {}, nodes = []) {
284
+ const liveOperations = manifest.liveOperations || {};
285
+ const receipts = Array.isArray(liveOperations.receipts) ? liveOperations.receipts : [];
286
+ const updateReceipts = receipts.filter((receipt) => receipt.operation === 'update-live-lineage');
287
+ const prepareReceipts = receipts.filter((receipt) => receipt.operation === 'prepare-live-response');
288
+ const artifactChange = updateReceipts.filter((receipt) => receipt.decision === 'artifact-change');
289
+ const noArtifactChange = updateReceipts.filter((receipt) => receipt.decision === 'no-artifact-change');
290
+ const touchesBySlug = new Map();
291
+ for (const receipt of updateReceipts) {
292
+ for (const artifactId of Array.isArray(receipt.artifactIds) ? receipt.artifactIds : []) {
293
+ const key = String(artifactId || '').trim();
294
+ if (!key) continue;
295
+ const current = touchesBySlug.get(key) || { latestTurnSequence: 0, latestObservedAt: '' };
296
+ const turnSequence = Number(receipt.turnSequence || 0);
297
+ if (turnSequence >= current.latestTurnSequence) touchesBySlug.set(key, { latestTurnSequence: turnSequence, latestObservedAt: receipt.observedAt || current.latestObservedAt });
298
+ }
299
+ }
300
+ for (const node of nodes) {
301
+ const touch = touchesBySlug.get(node.slug) || touchesBySlug.get(node.id) || touchesBySlug.get(slugFromPath(node.path));
302
+ if (touch) node.liveTouch = touch;
303
+ }
304
+ return Object.freeze({
305
+ processedTurnCount: Number(liveOperations.latestTurnSequence || updateReceipts.length || liveOperations.counts?.['update-live-lineage'] || 0),
306
+ preparedTurnCount: Number(liveOperations.preparedTurnSequence || prepareReceipts.length || liveOperations.counts?.['prepare-live-response'] || 0),
307
+ artifactChangeTurnCount: artifactChange.length,
308
+ noArtifactChangeTurnCount: noArtifactChange.length,
309
+ latestTurnSequence: Number(liveOperations.latestTurnSequence || 0),
310
+ latestEventSequence: Number(liveOperations.latestEventSequence || 0)
311
+ });
312
+ }
313
+
314
+ function parseManifest(input = {}) {
315
+ const files = Array.isArray(input.files) ? input.files : [];
316
+ const manifests = files.filter((file) => /(^|\/)manifest\.json$/i.test(String(file.path || file.name || '')) && typeof (file.content || file.markdown) === 'string');
317
+ for (const file of manifests) {
318
+ try { return JSON.parse(file.content || file.markdown || '{}'); }
319
+ catch { /* ignore invalid manifest */ }
320
+ }
321
+ if (input.manifest && typeof input.manifest === 'object') return input.manifest;
322
+ return {};
323
+ }
324
+
325
+ function normalizeLineageFindings(findings = []) {
326
+ return findings.map((finding) => portableFinding(finding.severity || 'info', finding.code || 'lineage.finding', finding.message || 'Lineage finding.', { nodeId: finding.nodeId || '', target: finding.target || '', source: finding.source || 'tiinex.lineage.v1' }));
327
+ }
328
+
329
+ function idsWithAncestors(model, ids = []) {
330
+ const out = new Set();
331
+ for (const id of ids) {
332
+ let current = id;
333
+ while (current && !out.has(current)) {
334
+ out.add(current);
335
+ current = model.parentByChild.get(current) || '';
336
+ }
337
+ }
338
+ return out;
339
+ }
340
+
341
+ function neighborhoodIds(model, id) {
342
+ const out = idsWithAncestors(model, [id]);
343
+ for (const child of model.childrenByParent.get(id) || []) out.add(child);
344
+ const parent = model.parentByChild.get(id);
345
+ if (parent) for (const sibling of model.childrenByParent.get(parent) || []) out.add(sibling);
346
+ return out;
347
+ }
348
+
349
+ function segmentIds(model, from, to, findings) {
350
+ const path = [];
351
+ let current = to;
352
+ while (current) {
353
+ path.push(current);
354
+ if (current === from) return new Set(path.reverse());
355
+ current = model.parentByChild.get(current) || '';
356
+ }
357
+ findings.push(portableFinding('warning', 'lineage-print.segment.not-connected', 'No loaded parent path connects the requested segment endpoints.', { from, to }));
358
+ return new Set([from, to]);
359
+ }
360
+
361
+ function hiddenParentPathToSelectedAncestor(model, id, selected) {
362
+ let current = model.parentByChild.get(id) || '';
363
+ const hiddenIds = [];
364
+ while (current) {
365
+ if (selected.has(current)) return { ancestorId: current, hiddenCount: hiddenIds.length, hiddenIds };
366
+ hiddenIds.push(current);
367
+ current = model.parentByChild.get(current) || '';
368
+ }
369
+ return { ancestorId: '', hiddenCount: hiddenIds.length, hiddenIds };
370
+ }
371
+
372
+ function resolveArtifactIds(model, values = []) {
373
+ return values.map((value) => resolveArtifactId(model, value)).filter(Boolean);
374
+ }
375
+
376
+ function resolveArtifactId(model, value = '') {
377
+ const raw = String(value || '').trim();
378
+ if (!raw) return '';
379
+ if (model.nodeById.has(raw)) return raw;
380
+ const lower = raw.toLowerCase();
381
+ const match = model.nodes.find((node) => node.path.toLowerCase() === lower || node.path.toLowerCase().endsWith(lower) || node.slug === lower || node.title.toLowerCase() === lower);
382
+ return match?.id || '';
383
+ }
384
+
385
+ function normalizeScope(value = '') { return String(value || 'all').trim() || 'all'; }
386
+ function emptyModel() { return { records: [], nodes: [], nodeById: new Map(), edges: [], parentEdges: [], missingParentEdges: [], roots: [], leaves: [], latestLeaves: [], live: liveStats({}, []) }; }
387
+ function emptyGraph() { return { nodes: [], edges: [], findings: [] }; }
388
+ function dedupeByCodeRef(findings = []) {
389
+ const seen = new Set();
390
+ const out = [];
391
+ for (const finding of findings) {
392
+ const key = [finding.code, finding.evidencePath || finding.ref || finding.nodeId || '', finding.target || '', finding.scope || '', finding.ancestorId || ''].join(':');
393
+ if (seen.has(key)) continue;
394
+ seen.add(key);
395
+ out.push(finding);
396
+ }
397
+ return out;
398
+ }
@@ -0,0 +1,88 @@
1
+ function nodeLabel(node = {}) {
2
+ const schema = node.schemaId ? ` [${node.schemaId}]` : '';
3
+ const path = node.path ? ` (${node.path})` : '';
4
+ return `${node.title || node.id}${schema}${path}`;
5
+ }
6
+
7
+ function compareNodeOrder(nodeById) {
8
+ return (a, b) => {
9
+ const an = typeof a === 'string' ? nodeById.get(a) || { id: a } : a;
10
+ const bn = typeof b === 'string' ? nodeById.get(b) || { id: b } : b;
11
+ return String(an.path || an.title || an.id).localeCompare(String(bn.path || bn.title || bn.id));
12
+ };
13
+ }
14
+
15
+ function escapeMermaid(value = '') { return String(value).replace(/["<>]/g, ''); }
16
+ function escapeDot(value = '') { return String(value).replace(/\\/g, '\\\\').replace(/"/g, '\"'); }
17
+ function mermaidId(value = '') { return `n_${String(value || '').replace(/[^A-Za-z0-9_]/g, '_')}`; }
18
+
19
+ export function renderTextMap(model, graph, scope, findings, manifest = {}) {
20
+ const lines = [];
21
+ lines.push('Tiinex lineage print');
22
+ lines.push(`Scope: ${scope}`);
23
+ lines.push(`Artifacts: ${model.nodes.length} | Selected: ${graph.nodes.length} | Roots: ${model.roots.length} | Leaves: ${model.leaves.length} | Parent edges: ${model.parentEdges.length}`);
24
+ if (model.live.processedTurnCount) lines.push(`Live receipts: processed turns ${model.live.processedTurnCount}, artifact-change turns ${model.live.artifactChangeTurnCount}, prepare turns ${model.live.preparedTurnCount}`);
25
+ const warningCount = findings.filter((finding) => finding.severity === 'warning' || finding.severity === 'error').length;
26
+ lines.push(`Findings: ${findings.length}${warningCount ? ` (${warningCount} warning/error)` : ''}`);
27
+ lines.push('');
28
+ lines.push('Tree');
29
+ const printed = new Set();
30
+ const selected = new Set(graph.nodes.map((node) => node.id));
31
+ const roots = graph.nodes.filter((node) => !model.parentByChild.has(node.id) || !selected.has(model.parentByChild.get(node.id))).map((node) => node.id).sort(compareNodeOrder(model.nodeById));
32
+ for (const root of roots) printSubtree(lines, model, selected, root, '', printed);
33
+ for (const node of graph.nodes) {
34
+ if (printed.has(node.id)) continue;
35
+ lines.push(`└─ ${nodeLabel(node)}`);
36
+ printed.add(node.id);
37
+ }
38
+ if (!graph.nodes.length) lines.push('└─ (no selected loaded artifacts)');
39
+ const hidden = graph.edges.filter((edge) => edge.status === 'hidden-intermediate' || edge.status === 'missing-parent' || edge.status === 'known-but-excluded');
40
+ if (hidden.length) {
41
+ lines.push('');
42
+ lines.push('Lineage gaps / scoped edges');
43
+ for (const edge of hidden) lines.push(`- ${edge.status}: ${edge.from || '(missing)'} → ${edge.to || '(missing)'}${edge.hiddenCount ? ` (${edge.hiddenCount} hidden)` : ''}`);
44
+ }
45
+ if (findings.length) {
46
+ lines.push('');
47
+ lines.push('Findings');
48
+ for (const finding of findings) lines.push(`- ${finding.severity}: ${finding.code}`);
49
+ }
50
+ return lines.join('\n');
51
+ }
52
+
53
+ function printSubtree(lines, model, selected, id, prefix, printed) {
54
+ const node = model.nodeById.get(id);
55
+ if (!node || printed.has(id) || !selected.has(id)) return;
56
+ const selectedChildren = (model.childrenByParent.get(id) || []).filter((child) => selected.has(child)).sort(compareNodeOrder(model.nodeById));
57
+ const connector = prefix ? '└─ ' : '└─ ';
58
+ lines.push(`${prefix}${connector}${nodeLabel(node)}`);
59
+ printed.add(id);
60
+ selectedChildren.forEach((child, index) => {
61
+ const nextPrefix = `${prefix}${index === selectedChildren.length - 1 ? ' ' : '│ '}`;
62
+ printSubtree(lines, model, selected, child, nextPrefix, printed);
63
+ });
64
+ }
65
+
66
+ export function renderMermaid(graph = {}) {
67
+ const lines = ['graph TD'];
68
+ for (const node of graph.nodes || []) lines.push(` ${mermaidId(node.id)}["${escapeMermaid(node.title || node.id)}"]`);
69
+ for (const edge of graph.edges || []) {
70
+ if (!edge.from || !edge.to) continue;
71
+ const arrow = edge.status === 'hidden-intermediate' ? '-. hidden .->' : '-->';
72
+ lines.push(` ${mermaidId(edge.from)} ${arrow} ${mermaidId(edge.to)}`);
73
+ }
74
+ return lines.join('\n');
75
+ }
76
+
77
+ export function renderDot(graph = {}) {
78
+ const lines = ['digraph tiinex_lineage {', ' rankdir=TB;'];
79
+ for (const node of graph.nodes || []) lines.push(` "${escapeDot(node.id)}" [label="${escapeDot(node.title || node.id)}"];`);
80
+ for (const edge of graph.edges || []) {
81
+ if (!edge.from || !edge.to) continue;
82
+ const style = edge.status === 'hidden-intermediate' ? ' [style=dashed,label="hidden"]' : '';
83
+ lines.push(` "${escapeDot(edge.from)}" -> "${escapeDot(edge.to)}"${style};`);
84
+ }
85
+ lines.push('}');
86
+ return lines.join('\n');
87
+ }
88
+
@@ -0,0 +1,58 @@
1
+ export function compactNode(node = {}) {
2
+ if (!node) return null;
3
+ return Object.freeze({
4
+ id: node.id,
5
+ slug: node.slug,
6
+ kind: node.kind || 'artifact',
7
+ status: node.status || 'included',
8
+ title: node.title || node.id,
9
+ path: node.path || '',
10
+ schemaId: node.schemaId || '',
11
+ sourceMode: node.sourceMode || '',
12
+ boundary: node.boundary || '',
13
+ summary: node.summary || '',
14
+ currentCreatedAt: node.currentCreatedAt || '',
15
+ lifecycleStatus: node.lifecycleStatus || '',
16
+ hasContinuityContext: Boolean(node.hasContinuityContext),
17
+ hasIntegrity: Boolean(node.hasIntegrity)
18
+ });
19
+ }
20
+
21
+ export function hasExplicitMetadata(markdown = '', labels = []) {
22
+ const text = String(markdown || '').toLowerCase();
23
+ return labels.some((label) => new RegExp(`(^|[\\n#*_ -])${escapeRegExp(label.toLowerCase())}([\\s:#*_ -]|$)`).test(text));
24
+ }
25
+
26
+ export function compareLatest(nodeById) {
27
+ return (a, b) => {
28
+ const an = nodeById.get(a) || {};
29
+ const bn = nodeById.get(b) || {};
30
+ const at = Number(an.liveTouch?.latestTurnSequence || 0);
31
+ const bt = Number(bn.liveTouch?.latestTurnSequence || 0);
32
+ if (bt !== at) return bt - at;
33
+ const ad = Date.parse(an.currentCreatedAt || '') || 0;
34
+ const bd = Date.parse(bn.currentCreatedAt || '') || 0;
35
+ if (bd !== ad) return bd - ad;
36
+ return compareNodeOrder(nodeById)(a, b);
37
+ };
38
+ }
39
+
40
+ export function compareNodeOrder(nodeById) {
41
+ return (a, b) => {
42
+ const an = typeof a === 'string' ? nodeById.get(a) || { id: a } : a;
43
+ const bn = typeof b === 'string' ? nodeById.get(b) || { id: b } : b;
44
+ return String(an.path || an.title || an.id).localeCompare(String(bn.path || bn.title || bn.id));
45
+ };
46
+ }
47
+
48
+ export function compareEdges(a = {}, b = {}) {
49
+ return [a.relation, a.from || '', a.to || '', a.status || ''].join('|').localeCompare([b.relation, b.from || '', b.to || '', b.status || ''].join('|'));
50
+ }
51
+
52
+ export function normalizeList(value = []) { return (Array.isArray(value) ? value : String(value || '').split(',')).map((entry) => String(entry || '').trim()).filter(Boolean); }
53
+ export function positiveInteger(value, fallback) { const number = Number.parseInt(value, 10); return Number.isFinite(number) && number > 0 ? number : fallback; }
54
+ export function truncate(value = '', max = 220) { const text = String(value || '').replace(/\s+/g, ' ').trim(); return text.length <= max ? text : `${text.slice(0, max - 1)}…`; }
55
+ export function slugFromPath(value = '') { const last = String(value || '').split('/').filter(Boolean).pop() || String(value || ''); return last.toLowerCase().replace(/\.trace\.md$/i, '').replace(/\.(md|markdown)$/i, ''); }
56
+ export function compareIds(a, b) { return String(a).localeCompare(String(b)); }
57
+
58
+ function escapeRegExp(value = '') { return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }