@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,173 @@
1
+ import { resolveLineage } from '../../../lineage/lineage.resolve.js';
2
+ import { parseArtifactMarkdown } from '../../../artifacts/artifact.parse.js';
3
+ import { auditPortableRecord } from '../audit/audit.capability.js';
4
+ import { normalizePortableInput } from '../input/portable.input.js';
5
+
6
+ const QUALIFIED_PARENT_STATUSES = new Set(['verified', 'resolved']);
7
+ const MAX_OBLIGATIONS = 64;
8
+
9
+ export function prepareLifecycleMaterial(input = {}, options = {}) {
10
+ const material = normalizePortableInput(input.materials || input);
11
+ const records = [...(material.records || [])];
12
+ const index = recordIndex(records);
13
+ const requested = String(input.controllingTask || input.task || options.controllingTask || '').trim();
14
+ const taskResolution = resolveUniqueRecord(records, requested);
15
+ const task = taskResolution.record;
16
+ const auditCache = new Map();
17
+ const qualification = task ? qualifyRecord(task, auditCache) : unresolvedQualification(taskResolution.state);
18
+ const criteria = task ? taskCriteria(task) : Object.freeze({ state: 'unresolved', sections: Object.freeze([]), basis: '' });
19
+ const lineage = resolveLineage(records, { depth: 'portable-lifecycle-readiness' });
20
+ const automatic = task && qualification.state === 'qualified'
21
+ ? directTaskObligations(task, records, lineage, auditCache)
22
+ : [];
23
+ const explicit = explicitWorkObligations(input.workObligations || input.obligations || [], records, auditCache);
24
+ const obligations = dedupeObligations([...automatic, ...explicit]);
25
+ const overflow = obligations.length > MAX_OBLIGATIONS;
26
+ const bounded = obligations.slice(0, MAX_OBLIGATIONS);
27
+
28
+ return Object.freeze({
29
+ material,
30
+ records: Object.freeze(records),
31
+ index,
32
+ auditCache,
33
+ lineage,
34
+ controllingTask: Object.freeze({
35
+ requested,
36
+ state: task && qualification.state === 'qualified' && criteria.state === 'qualified' ? 'qualified' : 'unresolved',
37
+ resolutionState: taskResolution.state,
38
+ record: task ? identity(task) : null,
39
+ qualification,
40
+ criteria
41
+ }),
42
+ obligations: Object.freeze(bounded),
43
+ obligationsOmitted: overflow ? obligations.length - MAX_OBLIGATIONS : 0,
44
+ lineageIssues: Object.freeze(relevantLineageIssues(lineage, new Set([task?.id, ...bounded.map((item) => item.task?.id)].filter(Boolean)))),
45
+ findings: Object.freeze([...(material.findings || []), ...(lineage.findings || [])]),
46
+ boundary: Object.freeze({
47
+ automaticWorkScope: 'direct qualified tiinex.task.v1 Parent continuity only',
48
+ typedWorkScope: 'explicit normalized workObligations whose semanticState is qualified; arbitrary Relation Type text is not interpreted here',
49
+ currentness: 'not inferred from filenames, timestamps, Root Status, lexical lifecycleStatus/currentStatus, branch state, or file absence',
50
+ maxObligations: MAX_OBLIGATIONS
51
+ })
52
+ });
53
+ }
54
+
55
+ export function qualifyRecord(record = {}, cache = new Map()) {
56
+ const key = String(record.id || record.path || '');
57
+ if (cache.has(key)) return cache.get(key);
58
+ const audit = auditPortableRecord(record);
59
+ const errors = (audit.findings || []).filter((item) => item.severity === 'error');
60
+ const qualified = Boolean(record.hasContinuityContext && record.hasIntegrity && audit.qualification?.exact && !errors.length);
61
+ const result = Object.freeze({
62
+ state: qualified ? 'qualified' : 'unresolved',
63
+ exact: qualified,
64
+ schemaId: String(record.schemaId || ''),
65
+ auditStatus: String(audit.status || ''),
66
+ findingCodes: Object.freeze(errors.map((item) => String(item.code || '')).filter(Boolean))
67
+ });
68
+ cache.set(key, result);
69
+ return result;
70
+ }
71
+
72
+ export function resolveFactRecord(material = {}, requested = '') {
73
+ const resolution = resolveUniqueRecord(material.records || [], requested);
74
+ if (!resolution.record) return Object.freeze({ state: resolution.state, record: null, qualification: unresolvedQualification(resolution.state) });
75
+ return Object.freeze({ state: resolution.state, record: resolution.record, qualification: qualifyRecord(resolution.record, material.auditCache) });
76
+ }
77
+
78
+ function taskCriteria(record = {}) {
79
+ let parsed;
80
+ try { parsed = parseArtifactMarkdown(record.markdown || ''); } catch { return Object.freeze({ state: 'unresolved', sections: Object.freeze([]), basis: 'parse-failed' }); }
81
+ const text = String(parsed.body?.text || '');
82
+ const names = ['Done Criteria', 'Acceptance Criteria'];
83
+ const sections = names.map((name) => ({ name, text: section(text, name) })).filter((item) => item.text);
84
+ return Object.freeze({
85
+ state: String(record.schemaId || '') === 'tiinex.task.v1' && sections.length ? 'qualified' : 'unresolved',
86
+ sections: Object.freeze(sections.map((item) => Object.freeze({ name: item.name, text: compact(item.text, 360) }))),
87
+ basis: sections.length ? 'qualified controlling Task criteria section(s)' : 'no Done Criteria or Acceptance Criteria section is available'
88
+ });
89
+ }
90
+
91
+ function directTaskObligations(task, records, lineage, auditCache) {
92
+ const byId = new Map(records.map((record) => [String(record.id || record.path || ''), record]));
93
+ const out = [];
94
+ for (const edge of lineage.edges || []) {
95
+ if (edge.kind !== 'parent' || edge.from !== task.id || !edge.to) continue;
96
+ const child = byId.get(String(edge.to));
97
+ if (!child || String(child.schemaId || '') !== 'tiinex.task.v1') continue;
98
+ const childQualification = qualifyRecord(child, auditCache);
99
+ const edgeQualified = QUALIFIED_PARENT_STATUSES.has(String(edge.status || '')) && childQualification.state === 'qualified';
100
+ out.push(Object.freeze({
101
+ id: `task-continuity:${child.id}`,
102
+ state: edgeQualified ? 'qualified' : 'unresolved',
103
+ kind: 'task-continuity',
104
+ task: identity(child),
105
+ relation: Object.freeze({ kind: 'parent', state: edgeQualified ? 'qualified' : 'unresolved', status: String(edge.status || ''), from: String(edge.from || ''), to: String(edge.to || ''), target: String(edge.target || '') }),
106
+ basis: 'direct qualified Task Parent continuity; Parent is not generalized beyond this Task-to-Task edge'
107
+ }));
108
+ }
109
+ return out;
110
+ }
111
+
112
+ function explicitWorkObligations(values = [], records = [], auditCache = new Map()) {
113
+ const list = Array.isArray(values) ? values : [];
114
+ return list.map((value, index) => {
115
+ const taskResolution = resolveUniqueRecord(records, value.task || value.path || value.source || '');
116
+ const task = taskResolution.record;
117
+ const taskQualification = task ? qualifyRecord(task, auditCache) : unresolvedQualification(taskResolution.state);
118
+ const semanticState = String(value.semanticState || value.state || 'unresolved');
119
+ const qualified = Boolean(task && taskQualification.state === 'qualified' && String(task.schemaId || '') === 'tiinex.task.v1' && semanticState === 'qualified' && nonEmptyBasis(value.basis));
120
+ return Object.freeze({
121
+ id: String(value.id || `explicit-work:${index + 1}:${task?.id || value.task || value.path || 'unresolved'}`),
122
+ state: qualified ? 'qualified' : 'unresolved',
123
+ kind: 'declared-typed-work',
124
+ task: task ? identity(task) : Object.freeze({ id: '', path: String(value.task || value.path || ''), schemaId: '' }),
125
+ relation: Object.freeze({ kind: 'declared-typed-work', state: qualified ? 'qualified' : 'unresolved', semanticState, predicate: String(value.predicate || value.relationType || ''), basis: compactBasis(value.basis) }),
126
+ basis: qualified ? 'explicit upstream-qualified typed work/provenance semantic fact' : 'typed work/provenance meaning or target qualification is unresolved'
127
+ });
128
+ });
129
+ }
130
+
131
+ function dedupeObligations(values = []) {
132
+ const byTask = new Map();
133
+ for (const value of values) {
134
+ const key = String(value.task?.id || value.task?.path || value.id || '');
135
+ const current = byTask.get(key);
136
+ if (!current || (current.state !== 'qualified' && value.state === 'qualified')) byTask.set(key, value);
137
+ }
138
+ return [...byTask.values()];
139
+ }
140
+
141
+ function relevantLineageIssues(lineage = {}, ids = new Set()) {
142
+ const issues = [];
143
+ for (const edge of lineage.edges || []) {
144
+ if (edge.kind !== 'parent' || !ids.has(edge.to)) continue;
145
+ if (!edge.from || ['missing', 'mismatch', 'ambiguous', 'degraded'].includes(String(edge.status || ''))) issues.push(Object.freeze({ code: `lineage.parent.${edge.status || 'missing'}`, nodeId: String(edge.to || ''), target: String(edge.target || ''), status: String(edge.status || '') }));
146
+ }
147
+ for (const finding of lineage.findings || []) {
148
+ if (!ids.has(String(finding.nodeId || ''))) continue;
149
+ if (/ambiguous|missing|mismatch|outOfBoundary/i.test(String(finding.code || ''))) issues.push(Object.freeze({ code: String(finding.code || ''), nodeId: String(finding.nodeId || ''), target: String(finding.target || ''), status: 'unresolved' }));
150
+ }
151
+ return uniqueBy(issues, (item) => `${item.code}|${item.nodeId}|${item.target}`);
152
+ }
153
+
154
+ function resolveUniqueRecord(records = [], requested = '') {
155
+ const wanted = normalizePath(requested);
156
+ if (!wanted) return { state: 'missing', record: null };
157
+ const exact = records.filter((record) => normalizePath(record.path) === wanted || String(record.id || '') === requested);
158
+ if (exact.length === 1) return { state: 'exact', record: exact[0] };
159
+ if (exact.length > 1) return { state: 'ambiguous', record: null };
160
+ const suffix = records.filter((record) => normalizePath(record.path).endsWith(`/${wanted}`));
161
+ return suffix.length === 1 ? { state: 'suffix', record: suffix[0] } : { state: suffix.length > 1 ? 'ambiguous' : 'missing', record: null };
162
+ }
163
+
164
+ function recordIndex(records = []) { const map = new Map(); for (const record of records) map.set(String(record.id || record.path || ''), record); return map; }
165
+ function identity(record = {}) { return Object.freeze({ id: String(record.id || record.path || ''), path: String(record.path || ''), title: String(record.title || ''), schemaId: String(record.schemaId || '') }); }
166
+ function unresolvedQualification(reason = '') { return Object.freeze({ state: 'unresolved', exact: false, schemaId: '', auditStatus: '', findingCodes: Object.freeze(reason ? [String(reason)] : []) }); }
167
+ function section(text = '', name = '') { const e = escape(name); return String(text).match(new RegExp(`(?:^|\\n)##\\s+${e}\\s*\\r?\\n([\\s\\S]*?)(?=\\n##\\s+|$)`, 'i'))?.[1]?.trim() || ''; }
168
+ function compact(value = '', limit = 360) { const text = String(value || '').replace(/\s+/g, ' ').trim(); return text.length > limit ? `${text.slice(0, limit - 1).trimEnd()}…` : text; }
169
+ function compactBasis(value) { return Array.isArray(value) ? Object.freeze(value.map((item) => typeof item === 'string' ? compact(item, 180) : Object.freeze({ ...item })).slice(0, 8)) : typeof value === 'string' ? compact(value, 360) : value && typeof value === 'object' ? Object.freeze({ ...value }) : null; }
170
+ function nonEmptyBasis(value) { return Array.isArray(value) ? value.length > 0 : typeof value === 'string' ? Boolean(value.trim()) : Boolean(value && typeof value === 'object' && Object.keys(value).length); }
171
+ function normalizePath(value = '') { return String(value || '').replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\/+/, '').trim(); }
172
+ function escape(value = '') { return String(value || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
173
+ function uniqueBy(values, keyFn) { const seen = new Set(); return values.filter((value) => { const key = keyFn(value); if (seen.has(key)) return false; seen.add(key); return true; }); }
@@ -0,0 +1,34 @@
1
+ import { portableOperationResult as operationResult } from '../operation.result.js';
2
+ import { projectPortableLifecycleReadiness } from './lifecycle.readiness.js';
3
+
4
+ export function projectPortableLifecycleReadinessOperation(input = {}, options = {}) {
5
+ const projection = projectPortableLifecycleReadiness(input, options);
6
+ return operationResult('project-lifecycle-readiness', {
7
+ status: projection.status,
8
+ resultSchema: projection.schema,
9
+ controllingTask: projection.controllingTask,
10
+ readiness: projection.readiness,
11
+ retest: projection.retest,
12
+ closure: projection.closure,
13
+ currentRepresentatives: projection.currentRepresentatives,
14
+ blockers: projection.blockers,
15
+ missingEvidence: projection.missingEvidence,
16
+ ambiguities: projection.ambiguities,
17
+ authorityBasis: projection.authorityBasis,
18
+ nextAction: projection.nextAction,
19
+ boundary: projection.boundary,
20
+ findings: projection.findings || []
21
+ });
22
+ }
23
+
24
+ export const portableLifecycleOperationDescriptors = Object.freeze([
25
+ Object.freeze({
26
+ name: 'project-lifecycle-readiness',
27
+ description: 'Project one exact controlling Task into separate derived readiness, authoritative re-test, and explicit closure surfaces from qualified Task continuity plus explicit normalized currentness/authority evidence, failing closed on ambiguity.',
28
+ safety: 'read-only-projection',
29
+ inputSchema: 'tiinex.portable.lifecycle-readiness.request.v1',
30
+ sourceMutation: false,
31
+ remoteWrite: false,
32
+ handler: projectPortableLifecycleReadinessOperation
33
+ })
34
+ ]);
@@ -0,0 +1,247 @@
1
+ import { portableFinding, summarizePortableFindings } from '../findings.js';
2
+ import { prepareLifecycleMaterial, resolveFactRecord } from './lifecycle.material.js';
3
+ import { nextLifecycleAction } from './lifecycle.action.js';
4
+
5
+ export const PORTABLE_LIFECYCLE_READINESS_SCHEMA_ID = 'tiinex.portable.lifecycle-readiness.v1';
6
+ const VALID_REP_STATES = new Set(['resolved', 'active', 'blocked', 'unresolved']);
7
+ const VALID_RETEST = new Set(['passed', 'failed']);
8
+ const MAX_FACTS = 96;
9
+
10
+ export function projectPortableLifecycleReadiness(input = {}, options = {}) {
11
+ const material = prepareLifecycleMaterial(input, options);
12
+ const facts = normalizedFacts(input);
13
+ const missingEvidence = [];
14
+ const ambiguities = [];
15
+ const blockers = [];
16
+ const task = material.controllingTask;
17
+
18
+ if (task.state !== 'qualified') missingEvidence.push(issue('controlling-task-unqualified', 'The exact controlling Task and its completion/acceptance criteria must qualify before readiness can be projected.'));
19
+ if (material.obligationsOmitted) ambiguities.push(issue('obligation-set-over-bounded-limit', `${material.obligationsOmitted} required work obligation(s) exceed the bounded evaluator limit.`));
20
+ if (material.lineageIssues.length) ambiguities.push(...material.lineageIssues.map((item) => issue(item.code, `Relevant Parent lineage remains ${item.status || 'unresolved'} for ${item.nodeId || item.target || 'work evidence'}.`)));
21
+
22
+ const authority = criteriaAuthority(facts.authority);
23
+ if (authority.state !== 'qualified') missingEvidence.push(issue('criteria-authority-unresolved', 'The authority that owns the controlling criteria is not explicitly qualified.'));
24
+
25
+ const representativeProjection = projectRepresentatives(material, facts.representatives, missingEvidence, ambiguities, blockers);
26
+ const blockerProjection = projectBlockers(material, facts.blockers, ambiguities, blockers);
27
+ const inputProjection = projectRetestInputs(facts.retestInputs, missingEvidence, ambiguities, blockers);
28
+ const retest = projectRetest(material, facts.retests, authority);
29
+ if (retest.state === 'unresolved') ambiguities.push(...retest.ambiguities);
30
+ const closure = projectClosure(material, facts.closures, authority, retest);
31
+ if (closure.state === 'unresolved') ambiguities.push(...closure.ambiguities);
32
+
33
+ const readiness = readinessProjection({ material, retest, closure, missingEvidence, ambiguities, blockers });
34
+ const nextAction = nextLifecycleAction({ readiness, retest, closure, blockers, missingEvidence, ambiguities, controllingTask: task.record });
35
+ const findings = Object.freeze([
36
+ ...(material.findings || []),
37
+ ...missingEvidence.map((item) => portableFinding('warning', `portable.lifecycle.${item.code}`, item.detail, { ref: task.record?.path || task.requested || '' })),
38
+ ...ambiguities.map((item) => portableFinding('warning', `portable.lifecycle.${item.code}`, item.detail, { ref: task.record?.path || task.requested || '' }))
39
+ ]);
40
+
41
+ return Object.freeze({
42
+ schema: PORTABLE_LIFECYCLE_READINESS_SCHEMA_ID,
43
+ status: closure.state === 'closed' || (task.state === 'qualified' && readiness.state !== 'unresolved' && retest.state !== 'unresolved' && closure.state !== 'unresolved') ? 'qualified-projection' : 'unresolved',
44
+ controllingTask: Object.freeze({ state: task.state, requested: task.requested, record: task.record, criteria: task.criteria }),
45
+ readiness,
46
+ retest,
47
+ closure,
48
+ currentRepresentatives: representativeProjection.current,
49
+ blockers: Object.freeze(blockers),
50
+ missingEvidence: Object.freeze(missingEvidence),
51
+ ambiguities: Object.freeze(ambiguities),
52
+ authorityBasis: authority,
53
+ nextAction,
54
+ findingSummary: summarizePortableFindings(findings),
55
+ findings,
56
+ boundary: Object.freeze({
57
+ adapterNeutral: true,
58
+ sharedConsumers: Object.freeze(['CLI', 'LLM', 'Viewer', 'VS Code']),
59
+ projectionOnly: true,
60
+ canonicalArtifactTruthPersisted: false,
61
+ canonicalSchemaVocabularyChanged: false,
62
+ parentMeaning: 'direct Task continuity only where exact qualified Task-to-Task Parent evidence exists',
63
+ semanticFacts: 'representative/currentness/blocker/re-test/closure/authority facts must arrive as explicit upstream-qualified normalized evidence; free prose and lexical lifecycle tokens are not interpreted as authority',
64
+ reductionMeaning: 'Reduction may satisfy only representative/re-test-input availability within explicit normalized carry-forward/loss facts; Reduction existence is never completion proof',
65
+ destructiveReduction: false,
66
+ remoteWrite: false,
67
+ sourceMutation: false
68
+ })
69
+ });
70
+ }
71
+
72
+ function projectRepresentatives(material, values, missingEvidence, ambiguities, blockers) {
73
+ const current = [];
74
+ const byObligation = new Map();
75
+ for (const raw of values.slice(0, MAX_FACTS)) {
76
+ const obligation = matchObligation(material.obligations, raw.obligation || raw.task || '');
77
+ if (!obligation) { ambiguities.push(issue('representative-obligation-unresolved', `Representative fact targets unknown obligation ${raw.obligation || raw.task || '(empty)'}.`)); continue; }
78
+ const recordResolution = resolveFactRecord(material, raw.representative || raw.path || obligation.task.path);
79
+ const semanticQualified = String(raw.qualification || raw.semanticState || '') === 'qualified' && nonEmptyBasis(raw.basis);
80
+ const state = VALID_REP_STATES.has(String(raw.state || '')) ? String(raw.state) : 'unresolved';
81
+ const currentness = String(raw.currentness || 'unresolved');
82
+ const exactQualified = Boolean(recordResolution.record && recordResolution.qualification.state === 'qualified' && semanticQualified);
83
+ const projection = Object.freeze({
84
+ obligation: obligation.task,
85
+ representative: recordResolution.record ? identity(recordResolution.record) : Object.freeze({ id: '', path: String(raw.representative || raw.path || '') }),
86
+ state,
87
+ currentness,
88
+ qualification: exactQualified ? 'qualified' : 'unresolved',
89
+ retestInputState: String(raw.retestInputState || raw.inputState || 'unresolved'),
90
+ reduction: reductionBoundary(recordResolution.record, raw),
91
+ basis: compactBasis(raw.basis)
92
+ });
93
+ const list = byObligation.get(obligation.id) || [];
94
+ list.push(projection);
95
+ byObligation.set(obligation.id, list);
96
+ }
97
+
98
+ for (const obligation of material.obligations) {
99
+ if (obligation.state !== 'qualified') { ambiguities.push(issue('work-obligation-unqualified', `Required work obligation ${obligation.task?.path || obligation.id} is not qualified.`)); continue; }
100
+ const facts = byObligation.get(obligation.id) || [];
101
+ const currentFacts = facts.filter((item) => item.currentness === 'current');
102
+ const qualifiedCurrent = currentFacts.filter((item) => item.qualification === 'qualified');
103
+ if (!facts.length) { missingEvidence.push(issue('current-representative-missing', `No explicit current representative assessment exists for required work ${obligation.task.path}.`)); continue; }
104
+ if (currentFacts.some((item) => item.qualification !== 'qualified')) { ambiguities.push(issue('current-representative-unqualified', `An apparent current representative for ${obligation.task.path} is not qualified.`)); continue; }
105
+ if (qualifiedCurrent.length !== 1) { ambiguities.push(issue('current-representative-ambiguous', `${obligation.task.path} has ${qualifiedCurrent.length} qualified current representatives; exactly one is required.`)); continue; }
106
+ const rep = qualifiedCurrent[0];
107
+ current.push(rep);
108
+ if (rep.state === 'active' || rep.state === 'blocked') blockers.push(blocker('required-work-current', rep.representative.path || obligation.task.path, rep.state, rep.basis));
109
+ else if (rep.state === 'unresolved') ambiguities.push(issue('current-representative-state-unresolved', `Current representative ${rep.representative.path} has unresolved work state.`));
110
+ if (rep.state === 'resolved') assessRepresentativeInput(rep, blockers, ambiguities);
111
+ }
112
+ return Object.freeze({ current: Object.freeze(current), assessedObligations: byObligation.size });
113
+ }
114
+
115
+ function assessRepresentativeInput(rep, blockers, ambiguities) {
116
+ if (rep.reduction.isReduction) {
117
+ if (rep.reduction.lossState === 'material') blockers.push(blocker('reduction-material-loss', rep.representative.path, 'known-missing-required-input', rep.basis));
118
+ else if (rep.reduction.lossState !== 'none') ambiguities.push(issue('reduction-loss-unresolved', `Reduction representative ${rep.representative.path} has unresolved material loss for re-test inputs.`));
119
+ }
120
+ if (rep.retestInputState === 'missing') blockers.push(blocker('representative-retest-input-missing', rep.representative.path, 'known-missing-required-input', rep.basis));
121
+ else if (rep.retestInputState !== 'available') ambiguities.push(issue('representative-retest-input-unresolved', `Re-test input availability is unresolved for ${rep.representative.path}.`));
122
+ }
123
+
124
+ function projectBlockers(material, values, ambiguities, blockers) {
125
+ const projected = [];
126
+ for (const raw of values.slice(0, MAX_FACTS)) {
127
+ const state = String(raw.state || 'unresolved');
128
+ const qualification = String(raw.qualification || raw.semanticState || '');
129
+ const currentness = String(raw.currentness || 'unresolved');
130
+ if (currentness === 'historical') continue;
131
+ if (qualification !== 'qualified' || !nonEmptyBasis(raw.basis) || currentness !== 'current') {
132
+ ambiguities.push(issue('blocker-currentness-unresolved', `Apparent blocker ${raw.id || raw.label || '(unnamed)'} is not both qualified and current.`));
133
+ continue;
134
+ }
135
+ const item = blocker(String(raw.kind || 'declared-blocker'), String(raw.target || raw.id || ''), state, raw.basis);
136
+ projected.push(item);
137
+ if (['blocking', 'active', 'disputed', 'incomplete'].includes(state)) blockers.push(item);
138
+ else if (!['resolved', 'clear'].includes(state)) ambiguities.push(issue('blocker-state-unresolved', `Qualified current blocker fact ${raw.id || raw.label || '(unnamed)'} has unresolved state ${state}.`));
139
+ }
140
+ return Object.freeze({ items: Object.freeze(projected) });
141
+ }
142
+
143
+ function projectRetestInputs(values, missingEvidence, ambiguities, blockers) {
144
+ const projected = [];
145
+ for (const raw of values.slice(0, MAX_FACTS)) {
146
+ const qualification = String(raw.qualification || raw.semanticState || '');
147
+ const state = String(raw.state || 'unresolved');
148
+ if (qualification !== 'qualified' || !nonEmptyBasis(raw.basis)) { ambiguities.push(issue('retest-input-unqualified', `Required re-test input ${raw.id || raw.label || '(unnamed)'} is not qualified.`)); continue; }
149
+ const item = Object.freeze({ id: String(raw.id || raw.label || ''), state, basis: compactBasis(raw.basis) });
150
+ projected.push(item);
151
+ if (state === 'missing') blockers.push(blocker('required-retest-input-missing', item.id, 'known-missing-required-input', item.basis));
152
+ else if (state !== 'available') ambiguities.push(issue('retest-input-state-unresolved', `Required re-test input ${item.id || '(unnamed)'} has unresolved availability.`));
153
+ }
154
+ return Object.freeze({ items: Object.freeze(projected), declared: values.length, missing: missingEvidence.length });
155
+ }
156
+
157
+ function projectRetest(material, values, authority) {
158
+ const apparent = values.slice(0, MAX_FACTS).filter((raw) => String(raw.currentness || 'current') !== 'historical');
159
+ if (!apparent.length) return retestResult('not-observed', [], [], [], null);
160
+ const qualified = [];
161
+ const ambiguities = [];
162
+ for (const raw of apparent) {
163
+ const record = resolveFactRecord(material, raw.artifact || raw.path || '');
164
+ const state = String(raw.state || raw.outcome || '');
165
+ const exactTarget = matchesTask(material.controllingTask.record, raw.target || raw.scope || '');
166
+ const valid = Boolean(record.record && record.qualification.state === 'qualified' && VALID_RETEST.has(state) && String(raw.qualification || raw.semanticState || '') === 'qualified' && String(raw.currentness || '') === 'current' && nonEmptyBasis(raw.basis) && exactTarget && String(raw.criteriaCoverage || '') === 'complete' && String(raw.methodState || raw.methodQualification || '') === 'qualified' && authorityMatches(authority, raw));
167
+ if (!valid) {
168
+ ambiguities.push(issue('retest-outcome-unqualified', `Apparent re-test outcome ${raw.artifact || raw.path || '(unresolved artifact)'} cannot qualify exact target, criteria coverage, method, currentness, or authority.`));
169
+ continue;
170
+ }
171
+ qualified.push(Object.freeze({ state, artifact: identity(record.record), authorityRole: String(raw.authorityRole || ''), authorityBasis: compactBasis(raw.authorityBasis || raw.basis), basis: compactBasis(raw.basis) }));
172
+ }
173
+ const states = new Set(qualified.map((item) => item.state));
174
+ if (ambiguities.length || qualified.length !== 1 || states.size !== 1) return retestResult('unresolved', qualified, apparent, ambiguities.length ? ambiguities : [issue('retest-outcome-ambiguous', `${qualified.length} qualified current re-test outcomes are present.`)], authority);
175
+ return retestResult(qualified[0].state, qualified, apparent, [], authority);
176
+ }
177
+
178
+ function projectClosure(material, values, authority, retest) {
179
+ const apparent = values.slice(0, MAX_FACTS).filter((raw) => String(raw.currentness || 'current') !== 'historical');
180
+ if (!apparent.length) return closureResult('open', [], [], [], null);
181
+ const qualified = [];
182
+ const ambiguities = [];
183
+ for (const raw of apparent) {
184
+ const record = resolveFactRecord(material, raw.artifact || raw.path || '');
185
+ const targetOk = matchesTask(material.controllingTask.record, raw.target || raw.scope || '');
186
+ const explicitClosed = String(raw.state || '') === 'closed' && raw.explicit !== false;
187
+ const authorityOk = authorityMatches(authority, raw);
188
+ const passOk = closurePassBasis(raw, retest, material, authority);
189
+ const valid = Boolean(record.record && record.qualification.state === 'qualified' && String(raw.qualification || raw.semanticState || '') === 'qualified' && String(raw.currentness || '') === 'current' && nonEmptyBasis(raw.basis) && targetOk && explicitClosed && authorityOk && passOk);
190
+ if (!valid) { ambiguities.push(issue('closure-disposition-unqualified', `Apparent closure ${raw.artifact || raw.path || '(unresolved artifact)'} cannot qualify exact target, explicit closure, pass basis, currentness, or authority.`)); continue; }
191
+ qualified.push(Object.freeze({ artifact: identity(record.record), authorityRole: String(raw.authorityRole || ''), passBasis: compactBasis(raw.passBasis || raw.incorporatedPass), basis: compactBasis(raw.basis) }));
192
+ }
193
+ if (ambiguities.length || qualified.length !== 1) return closureResult('unresolved', qualified, apparent, ambiguities.length ? ambiguities : [issue('closure-disposition-ambiguous', `${qualified.length} qualified current closures are present.`)], authority);
194
+ return closureResult('closed', qualified, apparent, [], authority);
195
+ }
196
+
197
+ function closurePassBasis(raw, retest, material, authority) {
198
+ const referenced = String(raw.passBasisArtifact || raw.retestArtifact || '').trim();
199
+ if (retest.state === 'passed' && (!referenced || retest.basis.some((item) => item.artifact.path === referenced || item.artifact.id === referenced))) return true;
200
+ const incorporated = raw.incorporatedPass;
201
+ if (!incorporated || typeof incorporated !== 'object') return false;
202
+ const state = String(incorporated.state || incorporated.outcome || '');
203
+ const record = resolveFactRecord(material, incorporated.artifact || raw.artifact || raw.path || '');
204
+ return Boolean(record.record && record.qualification.state === 'qualified' && state === 'passed' && String(incorporated.qualification || '') === 'qualified' && matchesTask(material.controllingTask.record, incorporated.target || raw.target || '') && String(incorporated.criteriaCoverage || '') === 'complete' && String(incorporated.methodState || '') === 'qualified' && authorityMatches(authority, incorporated));
205
+ }
206
+
207
+ function readinessProjection({ material, retest, closure, missingEvidence, ambiguities, blockers }) {
208
+ if (closure.state === 'closed') return readinessResult('not-applicable', ['qualified explicit closure already governs the exact controlling Task'], blockers, missingEvidence, ambiguities, material);
209
+ if (missingEvidence.length || ambiguities.length || closure.state === 'unresolved' || retest.state === 'unresolved') return readinessResult('unresolved', ['required qualification/currentness/authority evidence is unresolved'], blockers, missingEvidence, ambiguities, material);
210
+ if (retest.state === 'failed') return readinessResult('not-ready-for-retest', ['current authoritative re-test failed and has not been explicitly superseded by a newer qualified cycle'], blockers, missingEvidence, ambiguities, material);
211
+ if (blockers.length) return readinessResult('not-ready-for-retest', ['qualified current blocking prerequisite remains'], blockers, missingEvidence, ambiguities, material);
212
+ return readinessResult('ready-for-retest', ['all declared required work representatives and re-test inputs are qualified/current enough and no qualified current blocker remains'], blockers, missingEvidence, ambiguities, material);
213
+ }
214
+
215
+ function normalizedFacts(input) {
216
+ const facts = input.facts && typeof input.facts === 'object' ? input.facts : input;
217
+ return Object.freeze({
218
+ authority: facts.authority || {},
219
+ representatives: bounded(facts.representatives),
220
+ blockers: bounded(facts.blockers),
221
+ retestInputs: bounded(facts.retestInputs || facts.inputs),
222
+ retests: bounded(facts.retests || facts.outcomes),
223
+ closures: bounded(facts.closures)
224
+ });
225
+ }
226
+
227
+ function criteriaAuthority(value = {}) {
228
+ const owner = value.criteriaOwner || value.owner || value;
229
+ const role = String(owner.role || owner.roleLabel || '').trim();
230
+ const state = String(owner.state || owner.qualification || 'unresolved');
231
+ const qualified = state === 'qualified' && Boolean(role) && nonEmptyBasis(owner.basis);
232
+ return Object.freeze({ state: qualified ? 'qualified' : 'unresolved', role, basis: compactBasis(owner.basis), boundary: 'Explicit upstream-qualified governing authority only; authorship, holder identity, human presence, and report existence are not authority.' });
233
+ }
234
+
235
+ function authorityMatches(authority, raw = {}) { return authority.state === 'qualified' && String(raw.authorityState || raw.authorityQualification || 'qualified') === 'qualified' && String(raw.authorityRole || '').trim() === authority.role && nonEmptyBasis(raw.authorityBasis || raw.basis); }
236
+ function matchesTask(task, target) { const wanted = String(target || '').replace(/\\/g, '/').replace(/^\.\//, ''); return Boolean(task && wanted && [task.path, task.id].some((value) => value === wanted || String(value || '').endsWith(`/${wanted}`) || wanted.endsWith(`/${value}`))); }
237
+ function matchObligation(obligations, requested) { const wanted = String(requested || '').replace(/\\/g, '/').replace(/^\.\//, ''); return obligations.find((item) => [item.id, item.task?.id, item.task?.path].some((value) => value === wanted || (wanted && String(value || '').endsWith(`/${wanted}`)))); }
238
+ function reductionBoundary(record, raw) { const isReduction = String(record?.schemaId || '') === 'tiinex.reduction.v1'; return Object.freeze({ isReduction, carryForwardState: isReduction ? String(raw.carryForwardState || 'unresolved') : 'not-applicable', lossState: isReduction ? String(raw.lossState || 'unresolved') : 'not-applicable', validationState: isReduction ? String(raw.validationState || 'unresolved') : 'not-applicable', completionProof: false }); }
239
+ function retestResult(state, qualified, apparent, ambiguities, authority) { return Object.freeze({ state, basis: Object.freeze(qualified), apparentCount: apparent.length, ambiguities: Object.freeze(ambiguities), authorityBasis: authority?.state === 'qualified' ? authority : null, boundary: 'Outcome requires exact qualified target/coverage/method/currentness and matching governing authority; report existence/authorship alone is evidence only.' }); }
240
+ function closureResult(state, qualified, apparent, ambiguities, authority) { return Object.freeze({ state, basis: Object.freeze(qualified), apparentCount: apparent.length, ambiguities: Object.freeze(ambiguities), authorityBasis: state === 'closed' && authority?.state === 'qualified' ? authority : null, boundary: 'Closed requires explicit qualified governing disposition plus authoritative pass basis; convergence, cleanup, status, or pass alone do not close.' }); }
241
+ function readinessResult(state, reasons, blockers, missingEvidence, ambiguities, material) { return Object.freeze({ state, basis: Object.freeze({ controllingTask: material.controllingTask.record, criteria: material.controllingTask.criteria.basis, obligationCount: material.obligations.length, lineage: material.boundary.automaticWorkScope }), reasons: Object.freeze(reasons), blockers: Object.freeze([...blockers]), missingEvidence: Object.freeze([...missingEvidence]), ambiguities: Object.freeze([...ambiguities]) }); }
242
+ function blocker(code, target, state, basis) { return Object.freeze({ code, target: String(target || ''), state: String(state || ''), basis: compactBasis(basis) }); }
243
+ function issue(code, detail) { return Object.freeze({ code: String(code || 'unresolved'), detail: String(detail || '') }); }
244
+ function identity(record = {}) { return Object.freeze({ id: String(record.id || record.path || ''), path: String(record.path || ''), title: String(record.title || ''), schemaId: String(record.schemaId || '') }); }
245
+ function bounded(value) { return Object.freeze((Array.isArray(value) ? value : []).slice(0, MAX_FACTS)); }
246
+ function nonEmptyBasis(value) { return Array.isArray(value) ? value.length > 0 : typeof value === 'string' ? Boolean(value.trim()) : Boolean(value && typeof value === 'object' && Object.keys(value).length); }
247
+ function compactBasis(value) { if (Array.isArray(value)) return Object.freeze(value.slice(0, 8).map((item) => typeof item === 'string' ? item.slice(0, 240) : Object.freeze({ ...item }))); if (typeof value === 'string') return value.slice(0, 720); if (value && typeof value === 'object') return Object.freeze({ ...value }); return null; }
@@ -0,0 +1,22 @@
1
+ import { auditPortableRecords } from '../audit/audit.capability.js';
2
+
3
+ export function buildLineagePostRepairAudit(records = [], changedRecords = []) {
4
+ const postRepairAudit = auditPortableRecords(records);
5
+ const changedPathSet = new Set(changedRecords.map((record) => normalizePath(record.path || '')));
6
+ const changedAudits = Object.freeze((postRepairAudit.audits || []).filter((audit) => changedPathSet.has(normalizePath(audit.path || ''))));
7
+ const changedFindings = Object.freeze(changedAudits.flatMap((audit) => audit.findings || []));
8
+ return Object.freeze({
9
+ schema: 'tiinex.portable.lineage-integrity-post-repair-audit.v1',
10
+ status: postRepairAudit.status,
11
+ changedRecordStatus: changedRecords.length
12
+ ? (changedFindings.some((finding) => finding.severity === 'error') ? 'blocked' : changedFindings.some((finding) => finding.severity === 'warning') ? 'degraded' : 'clean')
13
+ : 'not-applicable',
14
+ changedAudits,
15
+ changedFindings,
16
+ findingSummary: postRepairAudit.findingSummary,
17
+ capabilityBoundary: postRepairAudit.boundary,
18
+ boundary: 'First-class post-application re-audit through the same shared audit capability used by CLI/LLM and Viewer consumers. Re-audit does not publish or mutate source material.'
19
+ });
20
+ }
21
+
22
+ function normalizePath(value = '') { return String(value || '').replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\/+|\/+$/g, ''); }
@@ -0,0 +1,36 @@
1
+ import { parseArtifactMarkdown } from '../../../artifacts/artifact.parse.js';
2
+
3
+ export function targetAuthorizedByDeclaredParent(record, step, approval, desiredTarget) {
4
+ let parsed;
5
+ try { parsed = parseArtifactMarkdown(record?.markdown || ''); } catch { return false; }
6
+ const trace = String(parsed.envelope?.parent?.trace || '').trim();
7
+ const browse = String((parsed.envelope?.parent?.originEntries || []).find((entry) => entry.label === 'browse + git')?.target || '');
8
+ if (step?.action === 'update-parent-origin-permalink') return true;
9
+ if (step?.action === 'review-parent-target-mismatch' && approval?.targetDisposition === 'repaired-local-parent') return Boolean(trace && desiredTarget === trace);
10
+ return desiredTarget === (browse || trace);
11
+ }
12
+
13
+ export function providerMaterialMatches(providerEvidence = {}, target = '', parentMarkdown = '', allowHistoricalMismatch = false) {
14
+ const locator = parseGithubBlobTarget(target);
15
+ if (!locator) return false;
16
+ for (const observation of providerEvidence.observations || []) {
17
+ for (const file of observation.files || []) {
18
+ if (file.source?.repository !== locator.repository) continue;
19
+ if (String(file.source?.commit || file.source?.ref || '') !== locator.commit) continue;
20
+ if (normalizePath(file.source?.path || file.path || '') !== normalizePath(locator.path)) continue;
21
+ if (allowHistoricalMismatch || file.content === String(parentMarkdown || '')) return true;
22
+ }
23
+ }
24
+ return false;
25
+ }
26
+
27
+ function parseGithubBlobTarget(value = '') {
28
+ try {
29
+ const url = new URL(String(value || ''));
30
+ if (url.protocol !== 'https:' || url.hostname !== 'github.com') return null;
31
+ const parts = url.pathname.split('/').filter(Boolean);
32
+ if (parts.length < 5 || parts[2] !== 'blob' || !/^[0-9a-f]{40}$/.test(parts[3])) return null;
33
+ return Object.freeze({ repository: `${parts[0]}/${parts[1]}`, commit: parts[3], path: parts.slice(4).join('/') });
34
+ } catch { return null; }
35
+ }
36
+ function normalizePath(value = '') { return String(value || '').replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\/+|\/+$/g, ''); }