@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.
- package/LICENSE +201 -0
- package/NOTICE +31 -0
- package/README.md +45 -0
- package/package.json +176 -0
- package/src/actions/record.actions.js +312 -0
- package/src/adapters/adapter.contracts.js +143 -0
- package/src/adapters/archive/archive.adapter.js +502 -0
- package/src/adapters/archive/archive.portableChangeset.js +141 -0
- package/src/adapters/archive/archive.transport.js +124 -0
- package/src/artifacts/artifact.localDraft.js +27 -0
- package/src/artifacts/artifact.normalize.js +28 -0
- package/src/artifacts/artifact.parse.js +207 -0
- package/src/artifacts/artifact.record.js +83 -0
- package/src/audit/audit.run.js +103 -0
- package/src/audit/audit.summary.js +7 -0
- package/src/diagnostics/sourceBoundary.report.js +112 -0
- package/src/export/package.apply.js +349 -0
- package/src/export/package.builder.js +366 -0
- package/src/export/package.bytes.js +164 -0
- package/src/export/package.controlIntegrity.js +42 -0
- package/src/export/package.controlTopology.js +97 -0
- package/src/export/package.fileMap.js +174 -0
- package/src/export/package.manifest.js +401 -0
- package/src/export/package.preflight.js +204 -0
- package/src/export/package.sourceReference.js +81 -0
- package/src/export/package.workspaceContext.js +144 -0
- package/src/export/package.zip.js +128 -0
- package/src/export/tree.bundle.js +278 -0
- package/src/governance/governance.boundary.js +196 -0
- package/src/integrity/integrity.c14nV2.js +190 -0
- package/src/integrity/integrity.methodReference.js +73 -0
- package/src/integrity/integrity.validate.js +56 -0
- package/src/lineage/lineage.candidateResolution.js +46 -0
- package/src/lineage/lineage.githubIssueComment.js +106 -0
- package/src/lineage/lineage.githubIssueLocal.js +196 -0
- package/src/lineage/lineage.githubIssueTarget.js +89 -0
- package/src/lineage/lineage.integrity.js +133 -0
- package/src/lineage/lineage.materialPreference.js +26 -0
- package/src/lineage/lineage.model.js +63 -0
- package/src/lineage/lineage.parentAuthority.js +5 -0
- package/src/lineage/lineage.parentBinding.js +104 -0
- package/src/lineage/lineage.pathBasis.js +47 -0
- package/src/lineage/lineage.resolve.js +388 -0
- package/src/lineage/lineage.sourceScope.js +74 -0
- package/src/lineage/lineage.targetKeys.js +80 -0
- package/src/lineage/lineage.traverse.js +132 -0
- package/src/public/applicationProjection.js +236 -0
- package/src/public/companionResources.js +246 -0
- package/src/public/index.js +16 -0
- package/src/public/node.js +2 -0
- package/src/public/schemaAncestry.js +26 -0
- package/src/publication/publication.contract.js +196 -0
- package/src/publication/publication.preflight.js +159 -0
- package/src/publication/publication.targetContract.js +241 -0
- package/src/reingest/reingest.plan.js +162 -0
- package/src/release/plan.mjs +28 -0
- package/src/release/policy.mjs +100 -0
- package/src/release/run.mjs +74 -0
- package/src/schemas/capability.registry.js +226 -0
- package/src/schemas/companion.js +245 -0
- package/src/schemas/contracts.js +6 -0
- package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.js +14 -0
- package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.json +23 -0
- package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.runtime.json +4283 -0
- package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.source.js +9 -0
- package/src/schemas/coordination/project/tiinex.project.v1.schema.js +26 -0
- package/src/schemas/coordination/project/tiinex.project.v1.schema.json +23 -0
- package/src/schemas/coordination/project/tiinex.project.v1.schema.runtime.json +1985 -0
- package/src/schemas/coordination/project/tiinex.project.v1.schema.source.js +9 -0
- package/src/schemas/core/decision/tiinex.decision.v1.schema.js +14 -0
- package/src/schemas/core/decision/tiinex.decision.v1.schema.json +24 -0
- package/src/schemas/core/decision/tiinex.decision.v1.schema.runtime.json +1700 -0
- package/src/schemas/core/decision/tiinex.decision.v1.schema.source.js +9 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.capabilities.js +14 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.en.i18n.json +6 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.findings.js +9 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.presenter.js +1 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.schema.js +32 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.schema.json +24 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.schema.runtime.json +2184 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.schema.source.js +9 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.sv.i18n.json +6 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.transitions.js +1 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.validate.js +10 -0
- package/src/schemas/core/feedback/tiinex.feedback.v1.schema.js +14 -0
- package/src/schemas/core/feedback/tiinex.feedback.v1.schema.json +23 -0
- package/src/schemas/core/feedback/tiinex.feedback.v1.schema.runtime.json +1773 -0
- package/src/schemas/core/feedback/tiinex.feedback.v1.schema.source.js +9 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.capabilities.js +11 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.contract.js +40 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.en.i18n.json +9 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.findings.js +12 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.localMaterialization.js +89 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.presenter.js +8 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.js +34 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.json +23 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.runtime.json +2029 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.source.js +9 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.sv.i18n.json +9 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.transitions.js +1 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.validate.js +25 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.capabilities.js +14 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.en.i18n.json +6 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.findings.js +9 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.presenter.js +1 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.schema.js +31 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.schema.json +23 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.schema.runtime.json +2033 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.schema.source.js +9 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.sv.i18n.json +6 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.transitions.js +1 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.validate.js +10 -0
- package/src/schemas/core/relation/tiinex.relation.v1.capabilities.js +7 -0
- package/src/schemas/core/relation/tiinex.relation.v1.contract.js +3 -0
- package/src/schemas/core/relation/tiinex.relation.v1.en.i18n.json +4 -0
- package/src/schemas/core/relation/tiinex.relation.v1.findings.js +9 -0
- package/src/schemas/core/relation/tiinex.relation.v1.localMaterialization.js +153 -0
- package/src/schemas/core/relation/tiinex.relation.v1.presenter.js +3 -0
- package/src/schemas/core/relation/tiinex.relation.v1.schema.js +20 -0
- package/src/schemas/core/relation/tiinex.relation.v1.schema.json +23 -0
- package/src/schemas/core/relation/tiinex.relation.v1.schema.runtime.json +1668 -0
- package/src/schemas/core/relation/tiinex.relation.v1.schema.source.js +9 -0
- package/src/schemas/core/relation/tiinex.relation.v1.sv.i18n.json +4 -0
- package/src/schemas/core/relation/tiinex.relation.v1.transitions.js +1 -0
- package/src/schemas/core/relation/tiinex.relation.v1.validate.js +36 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.capabilities.js +14 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.contract.js +57 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.en.i18n.json +4 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.findings.js +13 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.presenter.js +3 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.js +20 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.json +24 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.runtime.json +3315 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.source.js +9 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.sv.i18n.json +4 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.transitions.js +1 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.validate.js +78 -0
- package/src/schemas/core/signal/tiinex.signal.v1.schema.js +14 -0
- package/src/schemas/core/signal/tiinex.signal.v1.schema.json +23 -0
- package/src/schemas/core/signal/tiinex.signal.v1.schema.runtime.json +1733 -0
- package/src/schemas/core/signal/tiinex.signal.v1.schema.source.js +9 -0
- package/src/schemas/core/task/tiinex.task.v1.capabilities.js +11 -0
- package/src/schemas/core/task/tiinex.task.v1.contract.js +3 -0
- package/src/schemas/core/task/tiinex.task.v1.en.i18n.json +15 -0
- package/src/schemas/core/task/tiinex.task.v1.findings.js +18 -0
- package/src/schemas/core/task/tiinex.task.v1.localMaterialization.js +148 -0
- package/src/schemas/core/task/tiinex.task.v1.presenter.js +8 -0
- package/src/schemas/core/task/tiinex.task.v1.schema.js +35 -0
- package/src/schemas/core/task/tiinex.task.v1.schema.json +23 -0
- package/src/schemas/core/task/tiinex.task.v1.schema.runtime.json +1708 -0
- package/src/schemas/core/task/tiinex.task.v1.schema.source.js +9 -0
- package/src/schemas/core/task/tiinex.task.v1.sv.i18n.json +15 -0
- package/src/schemas/core/task/tiinex.task.v1.transitions.js +3 -0
- package/src/schemas/core/task/tiinex.task.v1.validate.js +41 -0
- package/src/schemas/core/topic/tiinex.topic.v1.capabilities.js +14 -0
- package/src/schemas/core/topic/tiinex.topic.v1.creation.js +46 -0
- package/src/schemas/core/topic/tiinex.topic.v1.en.i18n.json +8 -0
- package/src/schemas/core/topic/tiinex.topic.v1.findings.js +11 -0
- package/src/schemas/core/topic/tiinex.topic.v1.localMaterialization.js +135 -0
- package/src/schemas/core/topic/tiinex.topic.v1.presenter.js +1 -0
- package/src/schemas/core/topic/tiinex.topic.v1.schema.js +34 -0
- package/src/schemas/core/topic/tiinex.topic.v1.schema.json +23 -0
- package/src/schemas/core/topic/tiinex.topic.v1.schema.runtime.json +1699 -0
- package/src/schemas/core/topic/tiinex.topic.v1.schema.source.js +9 -0
- package/src/schemas/core/topic/tiinex.topic.v1.sv.i18n.json +8 -0
- package/src/schemas/core/topic/tiinex.topic.v1.transitions.js +31 -0
- package/src/schemas/core/topic/tiinex.topic.v1.validate.js +11 -0
- package/src/schemas/creation.capability.js +289 -0
- package/src/schemas/creation.contracts.js +334 -0
- package/src/schemas/creation.executionSnapshot.js +79 -0
- package/src/schemas/creation.factoryQualification.js +73 -0
- package/src/schemas/creation.renderer.js +244 -0
- package/src/schemas/creation.representation.js +279 -0
- package/src/schemas/creation.rootMetadata.js +6 -0
- package/src/schemas/creation.schemaReferences.js +65 -0
- package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.js +14 -0
- package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.json +23 -0
- package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.runtime.json +1873 -0
- package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.source.js +9 -0
- package/src/schemas/discovery/tiinex.discovery.v1.schema.js +14 -0
- package/src/schemas/discovery/tiinex.discovery.v1.schema.json +23 -0
- package/src/schemas/discovery/tiinex.discovery.v1.schema.runtime.json +1839 -0
- package/src/schemas/discovery/tiinex.discovery.v1.schema.source.js +9 -0
- package/src/schemas/generic.artifact.module.js +25 -0
- package/src/schemas/party/organization/tiinex.party.organization.v1.schema.js +26 -0
- package/src/schemas/party/organization/tiinex.party.organization.v1.schema.json +23 -0
- package/src/schemas/party/organization/tiinex.party.organization.v1.schema.runtime.json +2249 -0
- package/src/schemas/party/organization/tiinex.party.organization.v1.schema.source.js +9 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.js +26 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.json +24 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.runtime.json +2091 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.source.js +9 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.capabilities.js +14 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.en.i18n.json +4 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.findings.js +1 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.presenter.js +1 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.js +29 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.json +21 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.runtime.json +2180 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.source.js +9 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.sv.i18n.json +4 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.transitions.js +1 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.validate.js +1 -0
- package/src/schemas/reduction/tiinex.reduction.v1.schema.js +26 -0
- package/src/schemas/reduction/tiinex.reduction.v1.schema.json +23 -0
- package/src/schemas/reduction/tiinex.reduction.v1.schema.runtime.json +1733 -0
- package/src/schemas/reduction/tiinex.reduction.v1.schema.source.js +9 -0
- package/src/schemas/reference.shapes.js +33 -0
- package/src/schemas/registry.js +36 -0
- package/src/schemas/resolver.js +13 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.capabilities.js +14 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.en.i18n.json +4 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.findings.js +1 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.presenter.js +1 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.schema.js +29 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.schema.json +21 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.schema.runtime.json +2093 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.schema.source.js +9 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.sv.i18n.json +4 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.transitions.js +1 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.validate.js +1 -0
- package/src/schemas/schema.factory.descriptor.js +104 -0
- package/src/schemas/schema.githubSourceTarget.js +131 -0
- package/src/schemas/schema.identity.js +10 -0
- package/src/schemas/schema.reference.js +133 -0
- package/src/schemas/schema.source.js +239 -0
- package/src/schemas/tiinex.root.v1.capabilities.js +14 -0
- package/src/schemas/tiinex.root.v1.classify.js +55 -0
- package/src/schemas/tiinex.root.v1.en.i18n.json +24 -0
- package/src/schemas/tiinex.root.v1.fallback.js +84 -0
- package/src/schemas/tiinex.root.v1.findings.js +19 -0
- package/src/schemas/tiinex.root.v1.presenter.js +5 -0
- package/src/schemas/tiinex.root.v1.schema.js +29 -0
- package/src/schemas/tiinex.root.v1.schema.json +24 -0
- package/src/schemas/tiinex.root.v1.schema.runtime.json +1574 -0
- package/src/schemas/tiinex.root.v1.schema.source.js +9 -0
- package/src/schemas/tiinex.root.v1.sv.i18n.json +24 -0
- package/src/schemas/tiinex.root.v1.transitions.js +1 -0
- package/src/schemas/tiinex.root.v1.validate.js +36 -0
- package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.js +14 -0
- package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.json +23 -0
- package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.runtime.json +2027 -0
- package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.source.js +9 -0
- package/src/schemas/validation/method/tiinex.validation.method.v1.schema.js +14 -0
- package/src/schemas/validation/method/tiinex.validation.method.v1.schema.json +23 -0
- package/src/schemas/validation/method/tiinex.validation.method.v1.schema.runtime.json +1848 -0
- package/src/schemas/validation/method/tiinex.validation.method.v1.schema.source.js +9 -0
- package/src/schemas/validation/report/tiinex.validation.report.v1.schema.js +14 -0
- package/src/schemas/validation/report/tiinex.validation.report.v1.schema.json +23 -0
- package/src/schemas/validation/report/tiinex.validation.report.v1.schema.runtime.json +2015 -0
- package/src/schemas/validation/report/tiinex.validation.report.v1.schema.source.js +9 -0
- package/src/schemas/workspace/tiinex.workspace.v1.capabilities.js +12 -0
- package/src/schemas/workspace/tiinex.workspace.v1.en.i18n.json +7 -0
- package/src/schemas/workspace/tiinex.workspace.v1.findings.js +5 -0
- package/src/schemas/workspace/tiinex.workspace.v1.presenter.js +27 -0
- package/src/schemas/workspace/tiinex.workspace.v1.schema.js +30 -0
- package/src/schemas/workspace/tiinex.workspace.v1.schema.json +23 -0
- package/src/schemas/workspace/tiinex.workspace.v1.schema.runtime.json +1596 -0
- package/src/schemas/workspace/tiinex.workspace.v1.schema.source.js +9 -0
- package/src/schemas/workspace/tiinex.workspace.v1.sv.i18n.json +7 -0
- package/src/schemas/workspace/tiinex.workspace.v1.transitions.js +10 -0
- package/src/schemas/workspace/tiinex.workspace.v1.validate.js +10 -0
- package/src/sources/github/github.issueTarget.js +127 -0
- package/src/sources/origin.references.js +249 -0
- package/src/sources/source.explicitTargets.js +49 -0
- package/src/sources/transport.levels.js +107 -0
- package/src/tooling/portable/adapters/cli/cli.cold-start-input.js +34 -0
- package/src/tooling/portable/adapters/cli/cli.command-input.js +455 -0
- package/src/tooling/portable/adapters/cli/cli.common-author.js +249 -0
- package/src/tooling/portable/adapters/cli/cli.common-output.js +330 -0
- package/src/tooling/portable/adapters/cli/cli.editor-assistance.js +13 -0
- package/src/tooling/portable/adapters/cli/cli.ground-materialize.js +96 -0
- package/src/tooling/portable/adapters/cli/cli.ground-recovery.js +99 -0
- package/src/tooling/portable/adapters/cli/cli.handoff-manufacture.js +345 -0
- package/src/tooling/portable/adapters/cli/cli.handoff-sibling-allocation.js +31 -0
- package/src/tooling/portable/adapters/cli/cli.help.js +80 -0
- package/src/tooling/portable/adapters/cli/cli.land.js +13 -0
- package/src/tooling/portable/adapters/cli/cli.local-output.js +72 -0
- package/src/tooling/portable/adapters/cli/cli.material-policy.js +6 -0
- package/src/tooling/portable/adapters/cli/cli.operator-bridge.js +18 -0
- package/src/tooling/portable/adapters/cli/cli.reduction-input.js +14 -0
- package/src/tooling/portable/adapters/cli/cli.run.js +434 -0
- package/src/tooling/portable/adapters/llm/llm.entrypoint.js +34 -0
- package/src/tooling/portable/adapters/node/checkpoint.verify.js +267 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.bootstrap.js +109 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.enumeration.js +94 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.js +193 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.multiRoot.js +49 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.packageParent.js +130 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.requirements.js +353 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.scope.js +147 -0
- package/src/tooling/portable/adapters/node/workspaceCarrier.manufacture.js +62 -0
- package/src/tooling/portable/assets/asset.operations.js +170 -0
- package/src/tooling/portable/audit/audit.capability.js +119 -0
- package/src/tooling/portable/bootstrap/artifact.result.selfverify.mjs +109 -0
- package/src/tooling/portable/bootstrap/bootstrap.case.mjs +43 -0
- package/src/tooling/portable/bootstrap/tiinex.llm.bootstrap.md +814 -0
- package/src/tooling/portable/bootstrap/tiinex.llm.bootstrap.pointer.json +25 -0
- package/src/tooling/portable/checkpoint/portable.checkpoint.js +89 -0
- package/src/tooling/portable/conformance/checkpoint.qualification.js +271 -0
- package/src/tooling/portable/draft/draft.create.js +389 -0
- package/src/tooling/portable/draft/draft.crud.js +175 -0
- package/src/tooling/portable/draft/draft.exact.js +173 -0
- package/src/tooling/portable/draft/draft.operations.js +265 -0
- package/src/tooling/portable/draft/draft.qualification.js +45 -0
- package/src/tooling/portable/draft/draft.set.js +193 -0
- package/src/tooling/portable/draft/draft.validation-context.js +7 -0
- package/src/tooling/portable/editor/authoring.parent.js +37 -0
- package/src/tooling/portable/editor/editor.assistance.js +221 -0
- package/src/tooling/portable/editor/staged.validation.js +96 -0
- package/src/tooling/portable/engine.facade.js +468 -0
- package/src/tooling/portable/findings.js +92 -0
- package/src/tooling/portable/grounding/grounding.capsule.js +128 -0
- package/src/tooling/portable/grounding/grounding.continuity.js +283 -0
- package/src/tooling/portable/grounding/grounding.participantAuthority.js +20 -0
- package/src/tooling/portable/grounding/grounding.planningContext.js +34 -0
- package/src/tooling/portable/grounding/grounding.readiness.authority.js +17 -0
- package/src/tooling/portable/grounding/grounding.readiness.js +316 -0
- package/src/tooling/portable/grounding/grounding.readiness.support.js +245 -0
- package/src/tooling/portable/grounding/grounding.sourceEvidence.js +71 -0
- package/src/tooling/portable/grounding/grounding.workContext.js +72 -0
- package/src/tooling/portable/grounding/grounding.workProvenance.js +153 -0
- package/src/tooling/portable/handoff/carrierLineage.js +214 -0
- package/src/tooling/portable/handoff/carrierProfile.js +54 -0
- package/src/tooling/portable/handoff/carrierProjection.js +193 -0
- package/src/tooling/portable/handoff/carrierProjection.routeQualification.js +228 -0
- package/src/tooling/portable/handoff/carrierProjection.shared.js +7 -0
- package/src/tooling/portable/handoff/carrierProjection.workspaces.js +54 -0
- package/src/tooling/portable/handoff/coldConsumerEntrypoint.js +185 -0
- package/src/tooling/portable/handoff/coldStartQualification.contract.js +184 -0
- package/src/tooling/portable/handoff/coldStartQualification.grounding.js +392 -0
- package/src/tooling/portable/handoff/coldStartQualification.js +22 -0
- package/src/tooling/portable/handoff/coldStartQualification.materials.js +364 -0
- package/src/tooling/portable/handoff/coldStartQualification.observation.js +220 -0
- package/src/tooling/portable/handoff/coldStartQualification.run.js +81 -0
- package/src/tooling/portable/handoff/coldStartQualification.shared.js +57 -0
- package/src/tooling/portable/handoff/coldStartRolePointers.js +39 -0
- package/src/tooling/portable/handoff/contextAudit.js +247 -0
- package/src/tooling/portable/handoff/contracts/tiinex.handoff.package.v1.schema.md +409 -0
- package/src/tooling/portable/handoff/handoffAuthoringPlan.js +35 -0
- package/src/tooling/portable/handoff/handoffEndpointProjection.js +61 -0
- package/src/tooling/portable/handoff/handoffLeafProjection.js +91 -0
- package/src/tooling/portable/handoff/humanOutputPresentation.js +21 -0
- package/src/tooling/portable/handoff/manufacture.js +84 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.binding.js +72 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.direct.js +160 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.indexes.js +36 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.js +247 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.projectionProvider.js +44 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.workspace.js +226 -0
- package/src/tooling/portable/handoff/materialClosure.descriptor.js +169 -0
- package/src/tooling/portable/handoff/materialClosure.inputBinding.js +372 -0
- package/src/tooling/portable/handoff/materialClosure.inputBinding.support.js +62 -0
- package/src/tooling/portable/handoff/materialClosure.materialized.js +143 -0
- package/src/tooling/portable/handoff/materialClosure.materials.js +116 -0
- package/src/tooling/portable/handoff/materialClosure.package.js +181 -0
- package/src/tooling/portable/handoff/materialClosure.plan.js +204 -0
- package/src/tooling/portable/handoff/materialClosure.readiness.js +36 -0
- package/src/tooling/portable/handoff/materialClosure.requirements.js +137 -0
- package/src/tooling/portable/handoff/operatorContextProjection.js +105 -0
- package/src/tooling/portable/handoff/pointerEntrypoint.js +138 -0
- package/src/tooling/portable/handoff/qualifiedHandoffFixture.js +34 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.build.js +321 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.closure.js +126 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.inspect.js +194 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.materials.js +207 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.projection.js +69 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.roles.js +166 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.routes.js +113 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.shared.js +87 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.workspaces.js +160 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirstPhase1.js +44 -0
- package/src/tooling/portable/handoff/recipientV2.artifactInspection.js +55 -0
- package/src/tooling/portable/handoff/recipientV2.artifacts.js +174 -0
- package/src/tooling/portable/handoff/recipientV2.coldProjection.js +24 -0
- package/src/tooling/portable/handoff/recipientV2.delivery.js +48 -0
- package/src/tooling/portable/handoff/recipientV2.endpointRolePointers.js +179 -0
- package/src/tooling/portable/handoff/recipientV2.entryContract.js +28 -0
- package/src/tooling/portable/handoff/recipientV2.humanOutput.js +78 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.helpers.js +218 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.js +194 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.pathToken.js +9 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.projection.js +58 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.workspaces.js +177 -0
- package/src/tooling/portable/handoff/recipientV2.lineage.js +142 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.build.js +147 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.constants.js +4 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.contract.js +101 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.helpers.js +126 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.js +185 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.js +12 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.shared.js +24 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.workspaceProjection.js +22 -0
- package/src/tooling/portable/handoff/recipientV2.pointer.js +40 -0
- package/src/tooling/portable/handoff/recipientV2.routeSelection.js +16 -0
- package/src/tooling/portable/handoff/recipientV2.topology.helpers.js +20 -0
- package/src/tooling/portable/handoff/recipientV2.topology.js +320 -0
- package/src/tooling/portable/handoff/recipientV2.topology.materials.js +70 -0
- package/src/tooling/portable/handoff/recipientV2.topology.workspaces.js +193 -0
- package/src/tooling/portable/handoff/recipientV2.transportManifest.js +123 -0
- package/src/tooling/portable/handoff/recipientV2.workspaceRepresentation.js +163 -0
- package/src/tooling/portable/handoff/routeArtifactConformance.js +130 -0
- package/src/tooling/portable/handoff/toolingBootstrap.js +67 -0
- package/src/tooling/portable/handoff/transportCompanion.js +175 -0
- package/src/tooling/portable/handoff/workspaceByteProvider.archive.js +95 -0
- package/src/tooling/portable/handoff/workspaceByteProvider.js +271 -0
- package/src/tooling/portable/handoff/workspaceCarrier.manufacture.js +93 -0
- package/src/tooling/portable/handoff/workspaceLandingPlan.js +142 -0
- package/src/tooling/portable/handoff/workspacePackageSources.js +105 -0
- package/src/tooling/portable/handoff/workspaceQualifiedReference.js +10 -0
- package/src/tooling/portable/handoff/workspaceSourceIdentity.js +52 -0
- package/src/tooling/portable/handoff/workspaceTargetConformance.js +134 -0
- package/src/tooling/portable/host/host.capabilities.js +181 -0
- package/src/tooling/portable/host/tool.bindings.js +357 -0
- package/src/tooling/portable/host/tool.receiptNormalization.js +141 -0
- package/src/tooling/portable/index.js +52 -0
- package/src/tooling/portable/input/node.input.js +184 -0
- package/src/tooling/portable/input/portable.input.js +249 -0
- package/src/tooling/portable/lifecycle/lifecycle.action.js +11 -0
- package/src/tooling/portable/lifecycle/lifecycle.material.js +173 -0
- package/src/tooling/portable/lifecycle/lifecycle.operations.js +34 -0
- package/src/tooling/portable/lifecycle/lifecycle.readiness.js +247 -0
- package/src/tooling/portable/lineage/lineage.integrity.apply.audit.js +22 -0
- package/src/tooling/portable/lineage/lineage.integrity.apply.evidence.js +36 -0
- package/src/tooling/portable/lineage/lineage.integrity.apply.js +306 -0
- package/src/tooling/portable/lineage/lineage.integrity.apply.structure.js +178 -0
- package/src/tooling/portable/lineage/lineage.integrity.plan.js +377 -0
- package/src/tooling/portable/lineage/lineage.integrity.projection.human.js +82 -0
- package/src/tooling/portable/lineage/lineage.integrity.projection.js +349 -0
- package/src/tooling/portable/lineage/lineage.operations.js +32 -0
- package/src/tooling/portable/lineage/lineage.print.js +398 -0
- package/src/tooling/portable/lineage/lineage.print.render.js +88 -0
- package/src/tooling/portable/lineage/lineage.print.utils.js +58 -0
- package/src/tooling/portable/lineage/lineage.publicationProviderReceipts.js +141 -0
- package/src/tooling/portable/lineage/lineage.publicationQualification.js +183 -0
- package/src/tooling/portable/lineage/lineage.search.js +301 -0
- package/src/tooling/portable/live/live.artifact.js +192 -0
- package/src/tooling/portable/live/live.export.js +107 -0
- package/src/tooling/portable/live/live.lineage.closure.js +71 -0
- package/src/tooling/portable/live/live.lineage.js +338 -0
- package/src/tooling/portable/live/live.protocol.js +181 -0
- package/src/tooling/portable/materialization/durable.materialize.js +162 -0
- package/src/tooling/portable/materialization/epistemic.plan.js +239 -0
- package/src/tooling/portable/materialization/loaded.parent.js +54 -0
- package/src/tooling/portable/materialization/materialization.facade.js +30 -0
- package/src/tooling/portable/operation.catalog.js +393 -0
- package/src/tooling/portable/operation.catalog.package.js +183 -0
- package/src/tooling/portable/operation.result.js +25 -0
- package/src/tooling/portable/orchestration/task.prepare.js +191 -0
- package/src/tooling/portable/output/artifact.result.package.js +308 -0
- package/src/tooling/portable/output/deterministic.zip.js +88 -0
- package/src/tooling/portable/output/node.artifact-set.js +223 -0
- package/src/tooling/portable/output/node.draft.js +41 -0
- package/src/tooling/portable/output/node.zip.js +39 -0
- package/src/tooling/portable/output/recipientV2.zip.js +59 -0
- package/src/tooling/portable/overview/blockingCue.js +16 -0
- package/src/tooling/portable/overview/operatingOverview.js +413 -0
- package/src/tooling/portable/package/generation.binding.js +314 -0
- package/src/tooling/portable/package/generation.binding.projection.js +128 -0
- package/src/tooling/portable/package/material.graph.js +236 -0
- package/src/tooling/portable/package/runtime.package.js +321 -0
- package/src/tooling/portable/package/schema.transition.companion.js +196 -0
- package/src/tooling/portable/package/semantic.package.graph.js +272 -0
- package/src/tooling/portable/package/semantic.package.js +203 -0
- package/src/tooling/portable/package/semantic.package.schema-resolution.js +158 -0
- package/src/tooling/portable/package/semantic.package.transition-registry.js +189 -0
- package/src/tooling/portable/package/semantic.package.types.js +18 -0
- package/src/tooling/portable/providers/schema.bootstrap.provenance.js +10 -0
- package/src/tooling/portable/providers/schema.provider.qualification.js +52 -0
- package/src/tooling/portable/providers/schema.providers.js +458 -0
- package/src/tooling/portable/publication/runtime.publication.js +53 -0
- package/src/tooling/portable/qualification.js +150 -0
- package/src/tooling/portable/reduction/reduction.composition.js +229 -0
- package/src/tooling/portable/reduction/reduction.eligibility.helpers.js +258 -0
- package/src/tooling/portable/reduction/reduction.eligibility.js +191 -0
- package/src/tooling/portable/reduction/reduction.operations.js +30 -0
- package/src/tooling/portable/reduction/reduction.preflight.js +85 -0
- package/src/tooling/portable/reduction/reduction.shared.js +173 -0
- package/src/tooling/portable/schema/bootstrap/canonical.pack.js +24 -0
- package/src/tooling/portable/schema/bootstrap/docs-3988951208eb9a8926e84ab42625d4b42fa00c2d/party/role/tiinex.party.role.v1.schema.md +289 -0
- package/src/tooling/portable/schema/bootstrap/docs-3988951208eb9a8926e84ab42625d4b42fa00c2d/validation/report/tiinex.validation.report.v1.schema.md +300 -0
- package/src/tooling/portable/schema/bootstrap/qualified-local-root/tiinex.root.v1.runtime-projection.json +48 -0
- package/src/tooling/portable/schema/bootstrap/qualified-local-root/tiinex.root.v1.schema.md +865 -0
- package/src/tooling/portable/schema/contract.compile.js +406 -0
- package/src/tooling/portable/schema/contract.compile.utils.js +9 -0
- package/src/tooling/portable/schema/contract.constraints.js +117 -0
- package/src/tooling/portable/schema/contract.envelope.validate.js +177 -0
- package/src/tooling/portable/schema/contract.field-domain.compile.js +399 -0
- package/src/tooling/portable/schema/contract.field-domain.js +247 -0
- package/src/tooling/portable/schema/contract.field-shape.compile.js +34 -0
- package/src/tooling/portable/schema/contract.inheritance.inline.js +103 -0
- package/src/tooling/portable/schema/contract.inheritance.js +210 -0
- package/src/tooling/portable/schema/contract.inheritance.record.js +76 -0
- package/src/tooling/portable/schema/contract.machine-shape.js +309 -0
- package/src/tooling/portable/schema/contract.project.js +81 -0
- package/src/tooling/portable/schema/contract.semantic-resolution.js +82 -0
- package/src/tooling/portable/schema/contract.validate.js +0 -0
- package/src/tooling/portable/schema/lexical.shape.v1.js +338 -0
- package/src/tooling/portable/schema/llm.companion.js +108 -0
- package/src/tooling/portable/schema/named.declarations.js +162 -0
- package/src/tooling/portable/schema/ordinary.contract.js +193 -0
- package/src/tooling/portable/schema/ordinary.fields.js +205 -0
- package/src/tooling/portable/schema/qualifiedLocalRoot.projection.js +70 -0
- package/src/tooling/portable/schema/qualifiedLocalRoot.runtime.js +170 -0
- package/src/tooling/portable/schema/schema.contract.js +465 -0
- package/src/tooling/portable/schema/schema.guide.js +326 -0
- package/src/tooling/portable/schema/schema.snapshot.js +119 -0
- package/src/tooling/portable/session/portable.session.js +145 -0
- package/src/tooling/portable/transfer/transfer.plan.js +102 -0
- package/src/transitions/record.transitions.js +484 -0
- package/src/transitions/transition.validate.js +129 -0
- package/src/validation/findings.js +76 -0
- package/src/validation/validateArtifact.js +216 -0
- package/src/workspaces/workspace.entrypointCapability.js +44 -0
- package/src/workspaces/workspace.materialRole.js +242 -0
- package/src/workspaces/workspace.recordPaths.js +426 -0
- package/tools/tiinex-portable.mjs +6 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { packageFileBytes, sha256Hex } from '../../../export/package.bytes.js';
|
|
2
|
+
|
|
3
|
+
export const PORTABLE_HANDOFF_MATERIAL_CANDIDATE_SCHEMA_ID = 'tiinex.portable.handoff-material-candidate.v1';
|
|
4
|
+
|
|
5
|
+
export function collectHandoffMaterialCandidates(input = {}) {
|
|
6
|
+
const out = [];
|
|
7
|
+
for (const material of input.materials || []) out.push(normalizeCandidate(material, { providerId: material.providerId || 'supplied-material', providerKind: material.providerKind || 'supplied-material' }));
|
|
8
|
+
for (const response of input.providerResults || []) {
|
|
9
|
+
const providerId = String(response.providerId || response.provider?.id || 'provider-result');
|
|
10
|
+
const providerKind = String(response.providerKind || response.provider?.kind || 'provider');
|
|
11
|
+
for (const candidate of response.candidates || response.materials || []) out.push(normalizeCandidate({ ...candidate, requirementId: candidate.requirementId || response.requirementId, referenceTarget: candidate.referenceTarget || response.referenceTarget }, { providerId, providerKind, responseStatus: response.status || '' }));
|
|
12
|
+
}
|
|
13
|
+
for (const prior of input.priorPackages || []) {
|
|
14
|
+
for (const candidate of prior.materials || []) out.push(normalizeCandidate({ ...candidate, priorPackageId: prior.id || prior.packageId || '', requirementId: candidate.requirementId }, { providerId: String(prior.providerId || `prior-package:${prior.id || prior.packageId || 'unknown'}`), providerKind: 'prior-package' }));
|
|
15
|
+
}
|
|
16
|
+
return Object.freeze(out.filter((item) => item.bytes > 0 || item.referenceTarget || item.requirementId));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function resolveRequirementMaterial(requirement = {}, candidates = [], recipient = {}, policy = {}) {
|
|
20
|
+
const target = String(requirement.reference?.target || '');
|
|
21
|
+
const capability = recipientCanResolveReference(recipient, target);
|
|
22
|
+
const exactRequirementCandidates = candidates.filter((candidate) => candidate.requirementId && candidate.requirementId === requirement.id);
|
|
23
|
+
const relevant = exactRequirementCandidates.length ? exactRequirementCandidates : candidates.filter((candidate) => candidateMatchesRequirement(candidate, requirement));
|
|
24
|
+
const withBytes = relevant.filter((candidate) => candidate.bytes > 0 && candidate.sha256);
|
|
25
|
+
const conflicts = withBytes.filter((candidate) => candidate.expectedSha256 && candidate.expectedSha256 !== candidate.sha256);
|
|
26
|
+
if (conflicts.length) return resolution('integrity-conflict', requirement, relevant, null, capability, 'Resolved bytes contradict declared expected integrity authority.');
|
|
27
|
+
const digests = [...new Set(withBytes.map((candidate) => candidate.sha256))];
|
|
28
|
+
if (digests.length > 1) return resolution('ambiguous', requirement, relevant, null, capability, 'Multiple provider/material candidates carry distinct exact bytes and no selection authority is supplied.');
|
|
29
|
+
const exactBound = withBytes.filter((candidate) => candidateBoundToRequirement(candidate, requirement));
|
|
30
|
+
if (withBytes.length && !exactBound.length && target) return resolution('unresolved', requirement, relevant, null, capability, 'Resolved bytes cannot be bound back to the requested exact material reference.');
|
|
31
|
+
const distinctExactCandidates = distinctCandidateAuthorities(exactBound);
|
|
32
|
+
if (distinctExactCandidates.length > 1) return resolution('ambiguous', requirement, relevant, null, capability, 'Multiple distinct provider/material candidates are bound to the same exact requested representation, but no provider-selection authority exists. Byte equality does not authorize choosing provider provenance by array order.');
|
|
33
|
+
if (capability && policy.preferReferenceWhenResolvable !== false && target) return resolution('reference-sufficient', requirement, relevant, null, capability, 'Recipient capability can resolve the exact declared material reference without embedding bytes.');
|
|
34
|
+
if (exactBound.length) {
|
|
35
|
+
const selected = exactBound[0];
|
|
36
|
+
return resolution('materialized', requirement, relevant, selected, capability, 'Exact bytes are available and bound to the requested representation.');
|
|
37
|
+
}
|
|
38
|
+
if (capability && target) return resolution('reference-sufficient', requirement, relevant, null, capability, 'Recipient capability can resolve the exact declared material reference.');
|
|
39
|
+
return resolution('unresolved', requirement, relevant, null, capability, target ? 'Exact required material is not currently resolvable or materialized.' : 'No exact Material Reference or explicitly bound local material is available.');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function recipientCanResolveReference(recipient = {}, target = '') {
|
|
43
|
+
if (!target) return false;
|
|
44
|
+
const exactTargets = new Set([
|
|
45
|
+
...(recipient.referenceTargets || []),
|
|
46
|
+
...(recipient.capabilities?.referenceTargets || []),
|
|
47
|
+
...(recipient.resolvableReferences || [])
|
|
48
|
+
].map(String));
|
|
49
|
+
return exactTargets.has(String(target));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function normalizeCandidate(value = {}, provider = {}) {
|
|
53
|
+
const data = packageFileBytes(value);
|
|
54
|
+
const suppliedSha = String(value.sha256 || value.integrity?.sha256 || '').toLowerCase();
|
|
55
|
+
const computedSha = data.byteLength ? sha256Hex(data) : '';
|
|
56
|
+
return deepFreeze({
|
|
57
|
+
schema: PORTABLE_HANDOFF_MATERIAL_CANDIDATE_SCHEMA_ID,
|
|
58
|
+
id: String(value.id || value.representationId || ''),
|
|
59
|
+
requirementId: String(value.requirementId || ''),
|
|
60
|
+
referenceTarget: String(value.referenceTarget || value.reference || value.source?.reference || value.source?.permalink || ''),
|
|
61
|
+
path: String(value.path || ''),
|
|
62
|
+
packagePath: String(value.packagePath || ''),
|
|
63
|
+
workspaceId: String(value.workspaceId || ''),
|
|
64
|
+
bytes: data.byteLength,
|
|
65
|
+
sha256: computedSha || suppliedSha,
|
|
66
|
+
expectedSha256: String(value.expectedSha256 || value.authority?.sha256 || '').toLowerCase(),
|
|
67
|
+
data,
|
|
68
|
+
mediaType: String(value.mediaType || value.type || 'application/octet-stream'),
|
|
69
|
+
provider: Object.freeze({ id: String(provider.providerId || ''), kind: String(provider.providerKind || ''), responseStatus: String(provider.responseStatus || ''), priorPackageId: String(value.priorPackageId || '') }),
|
|
70
|
+
provenance: Object.freeze(serializable(value.provenance || value.source || {})),
|
|
71
|
+
authority: Object.freeze(serializable(value.authority || {}))
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
function distinctCandidateAuthorities(candidates = []) {
|
|
77
|
+
const byIdentity = new Map();
|
|
78
|
+
for (const candidate of candidates) {
|
|
79
|
+
const identity = candidateAuthorityIdentity(candidate);
|
|
80
|
+
if (!byIdentity.has(identity)) byIdentity.set(identity, candidate);
|
|
81
|
+
}
|
|
82
|
+
return [...byIdentity.values()];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function candidateAuthorityIdentity(candidate = {}) {
|
|
86
|
+
return JSON.stringify(sortJson({
|
|
87
|
+
id: String(candidate.id || ''),
|
|
88
|
+
path: String(candidate.path || ''),
|
|
89
|
+
referenceTarget: String(candidate.referenceTarget || ''),
|
|
90
|
+
provider: candidate.provider || {},
|
|
91
|
+
provenance: candidate.provenance || {},
|
|
92
|
+
authority: candidate.authority || {}
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function sortJson(value) {
|
|
97
|
+
if (Array.isArray(value)) return value.map(sortJson);
|
|
98
|
+
if (!value || typeof value !== 'object') return value;
|
|
99
|
+
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, sortJson(value[key])]));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function candidateMatchesRequirement(candidate, requirement) {
|
|
103
|
+
if (candidate.requirementId && candidate.requirementId === requirement.id) return true;
|
|
104
|
+
const target = String(requirement.reference?.target || '');
|
|
105
|
+
return Boolean(target && candidate.referenceTarget === target);
|
|
106
|
+
}
|
|
107
|
+
function candidateBoundToRequirement(candidate, requirement) {
|
|
108
|
+
const target = String(requirement.reference?.target || '');
|
|
109
|
+
if (!target) return Boolean(candidate.requirementId === requirement.id && candidate.authority?.localIdentityQualified === true);
|
|
110
|
+
return candidate.referenceTarget === target;
|
|
111
|
+
}
|
|
112
|
+
function resolution(disposition, requirement, candidates, selected, capability, reason) {
|
|
113
|
+
return deepFreeze({ disposition, requirementId: requirement.id, requirementName: String(requirement.name || ''), classification: requirement.classification, referenceTarget: String(requirement.reference?.target || ''), routeWorkspaceId: String(requirement.routeWorkspaceId || ''), routePath: String(requirement.routePath || ''), sourceRequirementId: String(requirement.sourceRequirementId || ''), recipientReferenceCapability: Boolean(capability), selectedMaterial: selected, candidates: Object.freeze(candidates), reason });
|
|
114
|
+
}
|
|
115
|
+
function serializable(value = {}) { const out = {}; for (const [key, item] of Object.entries(value || {})) if (typeof item !== 'function' && typeof item !== 'undefined') out[key] = item; return out; }
|
|
116
|
+
function deepFreeze(value) { if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value; if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return value; for (const child of Object.values(value)) deepFreeze(child); return Object.freeze(value); }
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { buildExportPackageBundle, inspectExportPackageBundle } from '../../../export/package.builder.js';
|
|
2
|
+
import { buildExportPackageFileMap, finalizeFile } from '../../../export/package.fileMap.js';
|
|
3
|
+
import { packageFileBytes, sha256Hex, stableFingerprintBytes, utf8Bytes } from '../../../export/package.bytes.js';
|
|
4
|
+
import { packageMaterialRepresentationSha256 } from '../../../export/package.controlIntegrity.js';
|
|
5
|
+
import { roundTripPortableRuntimePackage } from '../package/runtime.package.js';
|
|
6
|
+
import { planRecipientRelativeHandoffMaterialClosure, qualifyWorkspaceMaterializationCorrelationEntry, workspaceMaterializationCorrelationKey } from './materialClosure.plan.js';
|
|
7
|
+
import { buildHandoffClosureDescriptor, HANDOFF_CLOSURE_DESCRIPTOR_PATH, inspectHandoffClosureDescriptor } from './materialClosure.descriptor.js';
|
|
8
|
+
import { qualifyHandoffMaterialClosurePlanReadiness } from './materialClosure.readiness.js';
|
|
9
|
+
import { qualifyHandoffMaterialClosurePlanInputBinding } from './materialClosure.inputBinding.js';
|
|
10
|
+
import { qualifyHandoffMaterializedOutput } from './materialClosure.materialized.js';
|
|
11
|
+
import { buildHandoffTransportCompanionProjection, HANDOFF_TRANSPORT_COMPANION_PATH, inspectHandoffTransportCompanion } from './transportCompanion.js';
|
|
12
|
+
import { buildHandoffCarrierProjection, HANDOFF_CARRIER_PROJECTION_PATH, inspectHandoffCarrierProjection } from './carrierProjection.js';
|
|
13
|
+
import { buildHandoffColdConsumerProjection, renderHandoffColdConsumerEntrypoint, HANDOFF_COLD_CONSUMER_ENTRYPOINT_PATH, inspectHandoffColdConsumerEntrypoint } from './coldConsumerEntrypoint.js';
|
|
14
|
+
import { buildHandoffPointerEntrypoints, inspectHandoffPointerEntrypoints, HANDOFF_POINTER_ENTRYPOINT_PREFIX } from './pointerEntrypoint.js';
|
|
15
|
+
|
|
16
|
+
export const PORTABLE_HANDOFF_TRANSPORT_PACKAGE_SCHEMA_ID = 'tiinex.portable.handoff-transport-package.v1';
|
|
17
|
+
|
|
18
|
+
export function buildRecipientRelativeHandoffTransportPackage(input = {}, options = {}) {
|
|
19
|
+
const plan = input.plan || planRecipientRelativeHandoffMaterialClosure(input, options);
|
|
20
|
+
const planReadiness = qualifyHandoffMaterialClosurePlanReadiness(plan);
|
|
21
|
+
const planInputBinding = qualifyHandoffMaterialClosurePlanInputBinding(plan, input, { externallySupplied: Boolean(input.plan) });
|
|
22
|
+
const materializedOutputQualification = qualifyHandoffMaterializedOutput(plan);
|
|
23
|
+
const baseBundle = input.baseBundle || buildExportPackageBundle(input.workspace || {}, { ...(input.packageInput || {}), ...(options.packageInput || {}) });
|
|
24
|
+
const extraFiles = [];
|
|
25
|
+
const packagedMaterial = [];
|
|
26
|
+
for (const entry of materializedOutputQualification.state === 'qualified' ? materializedOutputQualification.expected : []) {
|
|
27
|
+
const packagePath = materialPackagePath(entry);
|
|
28
|
+
const file = finalizeFile({ path: packagePath, kind: 'handoff-material', logicalKind: 'recipient-relative-material', entryId: entry.requirementId, mediaType: entry.mediaType || 'application/octet-stream', data: entry.data, boundary: 'Recipient-relative exact byte carrier. Canonical artifact/source/workspace authority remains external and is preserved in the closure descriptor.' });
|
|
29
|
+
extraFiles.push(file);
|
|
30
|
+
packagedMaterial.push(Object.freeze({ ...entry, packagePath: file.path, bytes: file.bytes, sha256: file.sha256 }));
|
|
31
|
+
}
|
|
32
|
+
const packagedWorkspaces = [];
|
|
33
|
+
const qualifiedWorkspaceByCorrelation = indexWorkspaceMaterializationTruth(plan.workspaceMaterializations || []);
|
|
34
|
+
const rawWorkspaceCorrelationCounts = countWorkspaceCorrelationKeys(input.workspaceMaterializations || []);
|
|
35
|
+
let workspaceCorrelationBlocked = false;
|
|
36
|
+
for (const workspace of input.workspaceMaterializations || []) {
|
|
37
|
+
const transportCorrelationKey = workspaceMaterializationCorrelationKey(workspace);
|
|
38
|
+
const correlation = resolveWorkspaceMaterializationTruth(qualifiedWorkspaceByCorrelation, transportCorrelationKey, rawWorkspaceCorrelationCounts.get(transportCorrelationKey) || 0);
|
|
39
|
+
const qualifiedWorkspace = correlation.workspace;
|
|
40
|
+
const correlationStatus = correlation.status;
|
|
41
|
+
if (correlationStatus !== 'qualified') workspaceCorrelationBlocked = true;
|
|
42
|
+
const workspaceId = String(qualifiedWorkspace?.id || workspace.id || workspace.workspaceId || 'workspace');
|
|
43
|
+
const packagedEntries = [];
|
|
44
|
+
for (const entry of workspace.entries || []) {
|
|
45
|
+
if (!hasBytes(entry)) continue;
|
|
46
|
+
const file = finalizeFile({ path: workspacePackagePath(workspace, entry, workspaceId), kind: 'handoff-workspace-material', logicalKind: 'recipient-relative-workspace-byte-carrier', entryId: `workspace:${workspaceId}:${entry.path || ''}`, mediaType: entry.mediaType || entry.type || 'application/octet-stream', data: packageFileBytes(entry), boundary: workspaceCarrierBoundary(qualifiedWorkspace) });
|
|
47
|
+
extraFiles.push(file);
|
|
48
|
+
packagedEntries.push(Object.freeze({ path: String(entry.path || ''), packagePath: file.path, bytes: file.bytes, sha256: file.sha256, referenceTarget: String(entry.referenceTarget || '') }));
|
|
49
|
+
}
|
|
50
|
+
packagedWorkspaces.push(Object.freeze({ id: workspaceId, transportCorrelationKey, correlationStatus, entries: Object.freeze(packagedEntries) }));
|
|
51
|
+
}
|
|
52
|
+
let bootstrapPath = '';
|
|
53
|
+
let bootstrapCarrierBlocked = false;
|
|
54
|
+
if (plan.bootstrap?.status === 'present') {
|
|
55
|
+
const bootstrapPresented = input.bootstrap?.present === true || input.bootstrap?.include === true;
|
|
56
|
+
const bootstrapData = packageFileBytes(input.bootstrap || {});
|
|
57
|
+
if (!bootstrapPresented || bootstrapData.byteLength === 0) {
|
|
58
|
+
bootstrapCarrierBlocked = true;
|
|
59
|
+
} else {
|
|
60
|
+
bootstrapPath = safePath(input.bootstrap?.path || 'tiinex.package/bootstrap.md');
|
|
61
|
+
extraFiles.push(finalizeFile({ path: bootstrapPath, kind: 'handoff-bootstrap', logicalKind: 'transport-orientation', mediaType: String(input.bootstrap?.mediaType || input.bootstrap?.type || 'text/markdown'), data: bootstrapData, boundary: 'Optional transport orientation only; not a Tiinex artifact or workspace lineage member.' }));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
let additionalTransportBlocked = false;
|
|
65
|
+
const additionalTransportPaths = new Set();
|
|
66
|
+
for (const entry of input.additionalTransportFiles || []) {
|
|
67
|
+
const filePath = safePath(entry.path || '');
|
|
68
|
+
const data = packageFileBytes(entry);
|
|
69
|
+
if (!filePath || data.byteLength === 0 || additionalTransportPaths.has(filePath) || reservedGeneratedPath(filePath)) {
|
|
70
|
+
additionalTransportBlocked = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
additionalTransportPaths.add(filePath);
|
|
74
|
+
extraFiles.push(finalizeFile({
|
|
75
|
+
path: filePath,
|
|
76
|
+
kind: String(entry.kind || 'handoff-transport-material'),
|
|
77
|
+
logicalKind: String(entry.logicalKind || 'recipient-relative-transport-material'),
|
|
78
|
+
entryId: String(entry.entryId || ''),
|
|
79
|
+
mediaType: String(entry.mediaType || entry.type || 'application/octet-stream'),
|
|
80
|
+
data,
|
|
81
|
+
boundary: String(entry.boundary || 'Additional recipient-relative transport byte; package placement does not create semantic authority.'),
|
|
82
|
+
sourceBoundary: String(entry.sourceBoundary || '')
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
const localRunId = String(input.localRunId || `handoff-closure:${stableFingerprintBytes(utf8Bytes(JSON.stringify({ handoff: plan.handoff, required: plan.requirements?.required?.map((x) => [x.requirementId, x.disposition]), reference: plan.requirements?.reference?.map((x) => [x.requirementId, x.disposition]) })))}`);
|
|
86
|
+
const descriptor = buildHandoffClosureDescriptor(plan, { materialized: packagedMaterial, workspaces: packagedWorkspaces, bootstrapPath, localRunId, planInputBinding, materializedOutputQualification });
|
|
87
|
+
const descriptorFile = finalizeFile({ path: HANDOFF_CLOSURE_DESCRIPTOR_PATH, kind: 'handoff-closure-descriptor', logicalKind: 'disposable-transport-control', mediaType: 'application/json', content: `${stablePrettyJson(descriptor)}\n`, boundary: descriptor.boundary });
|
|
88
|
+
const packageClosureStatus = planReadiness.state === 'qualified' && planReadiness.expectedRequiredClosureReady && planInputBinding.state === 'qualified' && materializedOutputQualification.state === 'qualified' && baseBundle.status !== 'blocked' && !workspaceCorrelationBlocked && !bootstrapCarrierBlocked && !additionalTransportBlocked ? (baseBundle.status === 'degraded' ? 'degraded' : 'ready') : 'blocked';
|
|
89
|
+
const projectionBundle = { ...baseBundle, files: [...(baseBundle.files || []), ...extraFiles, descriptorFile], handoffClosure: descriptor };
|
|
90
|
+
const carrierProjection = buildHandoffCarrierProjection({ bundle: projectionBundle, descriptor, carrierLineage: input.carrierLineage || null, routes: input.transportRoutes || input.handoffRoutes || [] });
|
|
91
|
+
const carrierFile = finalizeFile({ path: HANDOFF_CARRIER_PROJECTION_PATH, kind: 'handoff-carrier-projection', logicalKind: 'disposable-human-transport-projection', mediaType: 'application/json', content: `${stablePrettyJson(carrierProjection)}\n`, boundary: carrierProjection.boundary });
|
|
92
|
+
const pointerEntrypointProjection = buildHandoffPointerEntrypoints({ carrierProjection, createdAt: baseBundle.manifest?.createdAt || baseBundle.builtAt || '' });
|
|
93
|
+
const pointerEntrypointFiles = pointerEntrypointProjection.entries.map((entry) => finalizeFile({ path: entry.path, kind: 'handoff-route-pointer', logicalKind: 'disposable-package-orientation-projection', mediaType: 'text/markdown', content: entry.markdown, boundary: entry.boundary }));
|
|
94
|
+
const coldConsumerProjection = buildHandoffColdConsumerProjection({ carrierProjection });
|
|
95
|
+
const coldConsumerEntrypointFile = finalizeFile({ path: HANDOFF_COLD_CONSUMER_ENTRYPOINT_PATH, kind: 'handoff-cold-consumer-entrypoint', logicalKind: 'disposable-package-orientation-projection', mediaType: 'text/markdown', content: renderHandoffColdConsumerEntrypoint({ projection: coldConsumerProjection }), boundary: coldConsumerProjection.boundary });
|
|
96
|
+
const selectedHandoffConformanceReady = (carrierProjection.routes || []).length > 0 && (carrierProjection.routes || []).every((route) => route.conformance?.status === 'qualified');
|
|
97
|
+
const transportStatus = !selectedHandoffConformanceReady || (carrierProjection.mode === 'shared' && carrierProjection.status !== 'ready') ? 'blocked' : packageClosureStatus;
|
|
98
|
+
const transportCompanion = buildHandoffTransportCompanionProjection({ bundle: baseBundle, descriptor, packageStatus: transportStatus, participation: input.transportParticipation || input.participation || {} });
|
|
99
|
+
const companionFile = finalizeFile({ path: HANDOFF_TRANSPORT_COMPANION_PATH, kind: 'handoff-transport-companion', logicalKind: 'disposable-transport-projection', mediaType: 'application/json', content: `${stablePrettyJson(transportCompanion)}\n`, boundary: transportCompanion.boundary });
|
|
100
|
+
const oldFileMapPath = 'tiinex.package/file-map.json';
|
|
101
|
+
const buildReceiptPath = 'tiinex.package/build-receipt.json';
|
|
102
|
+
const baseGoverned = [...(baseBundle.files || []).filter((file) => ![oldFileMapPath, buildReceiptPath].includes(String(file.path || ''))), ...extraFiles, descriptorFile, carrierFile, ...pointerEntrypointFiles, coldConsumerEntrypointFile, companionFile].map(finalizeFile);
|
|
103
|
+
const materialRepresentationSha256 = packageMaterialRepresentationSha256(baseGoverned);
|
|
104
|
+
const priorBuildReceipt = parseJsonFile((baseBundle.files || []).find((file) => String(file.path || '') === buildReceiptPath)) || {};
|
|
105
|
+
const buildReceipt = Object.freeze({ ...priorBuildReceipt, materialRepresentationSha256, counts: Object.freeze({ ...(priorBuildReceipt.counts || {}), materialFiles: baseGoverned.filter((file) => file.path && !String(file.path).startsWith('tiinex.package/')).length }) });
|
|
106
|
+
const buildReceiptFile = finalizeFile({ path: buildReceiptPath, kind: 'package-build-receipt', mediaType: 'application/json', content: `${stablePrettyJson(buildReceipt)}\n` });
|
|
107
|
+
const governed = [...baseGoverned, buildReceiptFile].map(finalizeFile);
|
|
108
|
+
const fileMap = buildExportPackageFileMap(governed, { packageId: baseBundle.packageId || '' });
|
|
109
|
+
const fileMapFile = finalizeFile({ path: oldFileMapPath, kind: 'package-file-map', mediaType: 'application/json', content: `${stablePrettyJson(fileMap)}\n` });
|
|
110
|
+
const files = Object.freeze([...governed, fileMapFile]);
|
|
111
|
+
const status = transportStatus;
|
|
112
|
+
const bundle = deepFreeze({ ...baseBundle, schema: baseBundle.schema, status, files, fileMap, packageRepresentationSha256: fileMap.representationSha256, handoffClosure: descriptor, boundary: `${baseBundle.boundary} Recipient-relative Handoff closure descriptor/material are disposable transport controls and do not alter semantic Handoff or workspace truth.` });
|
|
113
|
+
const inspection = inspectExportPackageBundle(bundle);
|
|
114
|
+
const closureInspection = inspectHandoffClosureDescriptor(bundle);
|
|
115
|
+
const carrierInspection = inspectHandoffCarrierProjection(bundle);
|
|
116
|
+
const pointerEntrypointInspection = inspectHandoffPointerEntrypoints(bundle);
|
|
117
|
+
const coldConsumerEntrypointInspection = inspectHandoffColdConsumerEntrypoint(bundle);
|
|
118
|
+
const companionInspection = inspectHandoffTransportCompanion(bundle);
|
|
119
|
+
return deepFreeze({ schema: PORTABLE_HANDOFF_TRANSPORT_PACKAGE_SCHEMA_ID, status: inspection.status === 'valid' && closureInspection.status === 'valid' && carrierInspection.status === 'valid' && pointerEntrypointInspection.status === 'valid' && coldConsumerEntrypointInspection.status === 'valid' && companionInspection.status === 'valid' ? status : 'blocked', plan, planReadiness, planInputBinding, materializedOutputQualification, bundle, inspection, closureInspection, descriptor, carrierProjection, carrierInspection, pointerEntrypointProjection, pointerEntrypointInspection, coldConsumerProjection, coldConsumerEntrypointInspection, transportCompanion, companionInspection });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function roundTripRecipientRelativeHandoffTransportPackage(input = {}, options = {}) {
|
|
123
|
+
const built = input.bundle ? input : buildRecipientRelativeHandoffTransportPackage(input, options);
|
|
124
|
+
const bundle = built.bundle || input.bundle;
|
|
125
|
+
const runtime = roundTripPortableRuntimePackage({ bundle });
|
|
126
|
+
const closureInspection = inspectHandoffClosureDescriptor(bundle);
|
|
127
|
+
const carrierInspection = inspectHandoffCarrierProjection(bundle);
|
|
128
|
+
const pointerEntrypointInspection = inspectHandoffPointerEntrypoints(bundle);
|
|
129
|
+
const coldConsumerEntrypointInspection = inspectHandoffColdConsumerEntrypoint(bundle);
|
|
130
|
+
const companionInspection = inspectHandoffTransportCompanion(bundle);
|
|
131
|
+
const status = runtime.status.startsWith('passed') && closureInspection.status === 'valid' && carrierInspection.status === 'valid' && pointerEntrypointInspection.status === 'valid' && coldConsumerEntrypointInspection.status === 'valid' && companionInspection.status === 'valid' ? 'passed' : 'failed';
|
|
132
|
+
return deepFreeze({ schema: 'tiinex.portable.handoff-transport-package.roundtrip.v1', status, built, runtime, closureInspection, carrierInspection, pointerEntrypointInspection, coldConsumerEntrypointInspection, companionInspection, verification: Object.freeze({ descriptorPath: HANDOFF_CLOSURE_DESCRIPTOR_PATH, descriptorVerified: closureInspection.status === 'valid', carrierProjectionPath: HANDOFF_CARRIER_PROJECTION_PATH, carrierProjectionVerified: carrierInspection.status === 'valid', pointerEntrypointsVerified: pointerEntrypointInspection.status === 'valid', coldConsumerEntrypointPath: HANDOFF_COLD_CONSUMER_ENTRYPOINT_PATH, coldConsumerEntrypointVerified: coldConsumerEntrypointInspection.status === 'valid', companionPath: HANDOFF_TRANSPORT_COMPANION_PATH, companionVerified: companionInspection.status === 'valid', packageRoundtrip: runtime.status, requiredClosureReady: Boolean(built.plan?.requiredClosureReady) }) });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
function indexWorkspaceMaterializationTruth(items = []) {
|
|
137
|
+
const index = new Map();
|
|
138
|
+
for (const workspace of items) {
|
|
139
|
+
const qualification = qualifyWorkspaceMaterializationCorrelationEntry(workspace);
|
|
140
|
+
if (qualification.state !== 'qualified') continue;
|
|
141
|
+
const key = qualification.key;
|
|
142
|
+
const current = index.get(key);
|
|
143
|
+
if (!current) index.set(key, Object.freeze({ status: 'qualified', workspace }));
|
|
144
|
+
else index.set(key, Object.freeze({ status: 'ambiguous', workspace: null }));
|
|
145
|
+
}
|
|
146
|
+
return index;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function countWorkspaceCorrelationKeys(items = []) {
|
|
150
|
+
const counts = new Map();
|
|
151
|
+
for (const workspace of items) {
|
|
152
|
+
const key = workspaceMaterializationCorrelationKey(workspace);
|
|
153
|
+
counts.set(key, (counts.get(key) || 0) + 1);
|
|
154
|
+
}
|
|
155
|
+
return counts;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function resolveWorkspaceMaterializationTruth(index, key = '', rawCount = 0) {
|
|
159
|
+
if (!key || rawCount !== 1) return Object.freeze({ status: rawCount > 1 ? 'ambiguous' : 'unresolved', workspace: null });
|
|
160
|
+
const entry = index.get(String(key || ''));
|
|
161
|
+
if (!entry) return Object.freeze({ status: 'unresolved', workspace: null });
|
|
162
|
+
return entry;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
function workspaceCarrierBoundary(workspace = null) {
|
|
167
|
+
if (workspace?.qualification === 'qualified' && workspace?.materialization === 'complete') return 'Package-local complete-evidence-backed workspace byte carrier; directory shape is not completeness proof.';
|
|
168
|
+
if (workspace?.qualification && workspace.qualification !== 'qualified') return `Package-local partial workspace byte carrier; planner-qualified workspace truth is ${workspace.materialization || 'partial'}/${workspace.qualification}. Raw caller completeness claims are not package authority.`;
|
|
169
|
+
return 'Package-local partial workspace byte carrier; directory shape is not completeness proof.';
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function reservedGeneratedPath(value = '') { const path = String(value || ''); return path.startsWith(HANDOFF_POINTER_ENTRYPOINT_PREFIX) || ['tiinex.package/file-map.json', 'tiinex.package/build-receipt.json', HANDOFF_CLOSURE_DESCRIPTOR_PATH, HANDOFF_CARRIER_PROJECTION_PATH, HANDOFF_COLD_CONSUMER_ENTRYPOINT_PATH, HANDOFF_TRANSPORT_COMPANION_PATH].includes(path); }
|
|
173
|
+
function materialPackagePath(entry = {}) { return safePath(entry.requestedPackagePath || `handoff.material/${safeToken(entry.requirementId || 'material')}/material.bin`); }
|
|
174
|
+
function workspacePackagePath(workspace = {}, entry = {}, qualifiedWorkspaceId = '') { return safePath(entry.packagePath || `handoff.workspaces/${safeToken(qualifiedWorkspaceId || workspace.id || workspace.workspaceId || 'workspace')}/${safePath(entry.path || 'material.bin')}`); }
|
|
175
|
+
function safePath(value = '') { return String(value || '').replace(/\\/g, '/').replace(/^\/+/, '').split('/').filter((part) => part && part !== '.' && part !== '..').map((part) => part.replace(/[\u0000-\u001f<>:"|?*]/g, '_')).join('/') || 'material.bin'; }
|
|
176
|
+
function safeToken(value = '') { const raw = String(value || ''); const token = raw.trim().replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, ''); if (!token) return 'material'; if (token.length <= 100) return token; return `${token.slice(0, 87)}-${sha256Hex(utf8Bytes(raw)).slice(0, 12)}`; }
|
|
177
|
+
function hasBytes(value = {}) { return packageFileBytes(value).byteLength > 0; }
|
|
178
|
+
function parseJsonFile(file = {}) { try { return JSON.parse(new TextDecoder().decode(packageFileBytes(file))); } catch { return null; } }
|
|
179
|
+
function stablePrettyJson(value) { return JSON.stringify(sortJson(value), null, 2); }
|
|
180
|
+
function sortJson(value) { if (Array.isArray(value)) return value.map(sortJson); if (!value || typeof value !== 'object') return value; if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return undefined; return Object.fromEntries(Object.keys(value).sort().flatMap((key) => { const sorted = sortJson(value[key]); return typeof sorted === 'undefined' ? [] : [[key, sorted]]; })); }
|
|
181
|
+
function deepFreeze(value) { if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value; if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return value; for (const child of Object.values(value)) deepFreeze(child); return Object.freeze(value); }
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { projectHandoffMaterialRequirements } from './materialClosure.requirements.js';
|
|
2
|
+
import { collectHandoffMaterialCandidates, resolveRequirementMaterial } from './materialClosure.materials.js';
|
|
3
|
+
import { packageFileBytes, sha256Hex } from '../../../export/package.bytes.js';
|
|
4
|
+
import { buildHandoffMaterialClosurePlanInputBinding } from './materialClosure.inputBinding.js';
|
|
5
|
+
|
|
6
|
+
export const PORTABLE_HANDOFF_MATERIAL_CLOSURE_PLAN_SCHEMA_ID = 'tiinex.portable.handoff-material-closure-plan.v1';
|
|
7
|
+
|
|
8
|
+
export function planRecipientRelativeHandoffMaterialClosure(input = {}, options = {}) {
|
|
9
|
+
const findings = [];
|
|
10
|
+
const requirements = input.requirements || projectHandoffMaterialRequirements(input.handoff || {});
|
|
11
|
+
const candidates = collectHandoffMaterialCandidates(input);
|
|
12
|
+
const policy = Object.freeze({
|
|
13
|
+
preferReferenceWhenResolvable: input.preferReferenceWhenResolvable !== false,
|
|
14
|
+
includeReferenceMaterial: input.includeReferenceMaterial === true,
|
|
15
|
+
bootstrap: input.bootstrap?.present === true || input.bootstrap?.include === true ? 'present' : 'absent'
|
|
16
|
+
});
|
|
17
|
+
const required = requirements.required.map((requirement) => resolveRequirementMaterial(requirement, candidates, input.recipient || {}, policy));
|
|
18
|
+
const reference = requirements.reference.map((requirement) => referenceDisposition(requirement, candidates, input.recipient || {}, policy));
|
|
19
|
+
const endpointRoles = (requirements.endpointRoles || []).map((requirement) => resolveRequirementMaterial(requirement, candidates, input.recipient || {}, { ...policy, preferReferenceWhenResolvable: false }));
|
|
20
|
+
const participantRoles = (requirements.participantRoles || []).map((requirement) => resolveRequirementMaterial(requirement, candidates, input.recipient || {}, { ...policy, preferReferenceWhenResolvable: false }));
|
|
21
|
+
const dependencies = (requirements.dependencies || []).map((requirement) => resolveRequirementMaterial(requirement, candidates, input.recipient || {}, { ...policy, preferReferenceWhenResolvable: false }));
|
|
22
|
+
const workspaces = qualifyWorkspaceMaterializations(input.workspaceMaterializations || [], findings);
|
|
23
|
+
const inputBinding = buildHandoffMaterialClosurePlanInputBinding(requirements, input.recipient || {}, { required, reference, endpointRoles, participantRoles, dependencies }, { policy, bootstrap: input.bootstrap || {} });
|
|
24
|
+
const requiredBlocked = required.some((item) => ['unresolved', 'ambiguous', 'integrity-conflict'].includes(item.disposition));
|
|
25
|
+
const endpointRoleBlocked = endpointRoles.some((item) => ['unresolved', 'ambiguous', 'integrity-conflict'].includes(item.disposition));
|
|
26
|
+
const participantRoleBlocked = participantRoles.some((item) => ['unresolved', 'ambiguous', 'integrity-conflict'].includes(item.disposition));
|
|
27
|
+
const dependencyBlocked = dependencies.some((item) => ['unresolved', 'ambiguous', 'integrity-conflict'].includes(item.disposition));
|
|
28
|
+
const workspaceBlocked = workspaces.some((item) => String(item.qualification || '').startsWith('invalid-'));
|
|
29
|
+
const ready = !requiredBlocked && !endpointRoleBlocked && !participantRoleBlocked && !dependencyBlocked && !workspaceBlocked;
|
|
30
|
+
for (const item of required) if (['unresolved', 'ambiguous', 'integrity-conflict'].includes(item.disposition)) findings.push(finding('error', `portable.handoff-material.required.${item.disposition}`, item.reason, { requirementId: item.requirementId, referenceTarget: item.referenceTarget }));
|
|
31
|
+
for (const item of endpointRoles) if (['unresolved', 'ambiguous', 'integrity-conflict'].includes(item.disposition)) findings.push(finding('error', `portable.handoff-material.endpoint-role.${item.disposition}`, item.reason, { requirementId: item.requirementId, referenceTarget: item.referenceTarget }));
|
|
32
|
+
for (const item of participantRoles) if (['unresolved', 'ambiguous', 'integrity-conflict'].includes(item.disposition)) findings.push(finding('error', `portable.handoff-material.participant-role.${item.disposition}`, item.reason, { requirementId: item.requirementId, referenceTarget: item.referenceTarget }));
|
|
33
|
+
for (const item of dependencies) if (['unresolved', 'ambiguous', 'integrity-conflict'].includes(item.disposition)) findings.push(finding('error', `portable.handoff-material.dependency.${item.disposition}`, item.reason, { requirementId: item.requirementId, referenceTarget: item.referenceTarget }));
|
|
34
|
+
for (const item of reference) if (item.disposition === 'ambiguous' || item.disposition === 'integrity-conflict') findings.push(finding('warning', `portable.handoff-material.reference.${item.disposition}`, item.reason, { requirementId: item.requirementId, referenceTarget: item.referenceTarget }));
|
|
35
|
+
const materialized = [...required, ...reference, ...endpointRoles, ...participantRoles, ...dependencies].filter((item) => item.disposition === 'materialized' && item.selectedMaterial).map((item) => materializedPlanEntry(item));
|
|
36
|
+
return deepFreeze({
|
|
37
|
+
schema: PORTABLE_HANDOFF_MATERIAL_CLOSURE_PLAN_SCHEMA_ID,
|
|
38
|
+
status: ready ? 'ready' : 'blocked',
|
|
39
|
+
requiredClosureReady: ready,
|
|
40
|
+
semanticHandoffStatus: String(requirements.handoff?.semanticStatus || 'unknown'),
|
|
41
|
+
boundary: 'Recipient-relative disposable transport plan. It does not change Handoff validity/state, artifact identity, workspace ownership, provider semantics, or acceptance/completion.',
|
|
42
|
+
handoff: requirements.handoff,
|
|
43
|
+
inputBinding,
|
|
44
|
+
policy,
|
|
45
|
+
requirements: Object.freeze({ required: Object.freeze(required), reference: Object.freeze(reference), endpointRoles: Object.freeze(endpointRoles), participantRoles: Object.freeze(participantRoles), dependencies: Object.freeze(dependencies) }),
|
|
46
|
+
materialized: Object.freeze(materialized),
|
|
47
|
+
workspaceMaterializations: Object.freeze(workspaces),
|
|
48
|
+
bootstrap: Object.freeze({ status: policy.bootstrap, boundary: 'Optional transport orientation only; not Handoff semantics, workspace authority, or artifact identity.' }),
|
|
49
|
+
findings: Object.freeze([...(requirements.findings || []), ...findings])
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function referenceDisposition(requirement, candidates, recipient, policy) {
|
|
54
|
+
if (!policy.includeReferenceMaterial) {
|
|
55
|
+
const resolved = resolveRequirementMaterial(requirement, candidates, recipient, policy);
|
|
56
|
+
if (resolved.disposition === 'reference-sufficient') return resolved;
|
|
57
|
+
return Object.freeze({ ...resolved, disposition: 'omitted-by-plan', selectedMaterial: null, reason: 'Reference-only material was intentionally omitted by this recipient-relative plan.' });
|
|
58
|
+
}
|
|
59
|
+
return resolveRequirementMaterial(requirement, candidates, recipient, policy);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function materializedPlanEntry(item) {
|
|
63
|
+
const material = item.selectedMaterial || {};
|
|
64
|
+
return Object.freeze({
|
|
65
|
+
requirementId: item.requirementId,
|
|
66
|
+
classification: item.classification,
|
|
67
|
+
referenceTarget: item.referenceTarget,
|
|
68
|
+
routeWorkspaceId: item.routeWorkspaceId,
|
|
69
|
+
routePath: item.routePath,
|
|
70
|
+
sourceRequirementId: item.sourceRequirementId,
|
|
71
|
+
path: material.path,
|
|
72
|
+
requestedPackagePath: material.packagePath,
|
|
73
|
+
bytes: material.bytes,
|
|
74
|
+
sha256: material.sha256,
|
|
75
|
+
mediaType: material.mediaType,
|
|
76
|
+
provider: material.provider,
|
|
77
|
+
provenance: material.provenance,
|
|
78
|
+
authority: material.authority,
|
|
79
|
+
data: material.data
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function qualifyWorkspaceMaterializations(items, findings) {
|
|
84
|
+
return Object.freeze((items || []).map((item, index) => {
|
|
85
|
+
const qualified = qualifyWorkspaceMaterialization(item, index, findings);
|
|
86
|
+
const transportCorrelationEvidence = workspaceMaterializationCorrelationEvidence(item, qualified);
|
|
87
|
+
return deepFreeze({ ...qualified, transportCorrelationEvidence, transportCorrelationKey: workspaceMaterializationCorrelationKeyFromEvidence(transportCorrelationEvidence) });
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function qualifyWorkspaceMaterialization(item = {}, index = 0, findings = null) {
|
|
92
|
+
const requested = String(item.state || item.materialization || 'partial');
|
|
93
|
+
const completeEvidence = item.completenessEvidence?.state === 'qualified' || item.completeEvidence?.state === 'qualified';
|
|
94
|
+
const boundedEvidence = item.scopeEvidence?.state === 'qualified';
|
|
95
|
+
let qualification = 'qualified';
|
|
96
|
+
let materialization = 'partial';
|
|
97
|
+
if (requested === 'complete') {
|
|
98
|
+
qualification = completeEvidence ? 'qualified' : 'invalid-completeness-claim';
|
|
99
|
+
materialization = completeEvidence ? 'complete' : 'partial';
|
|
100
|
+
} else if (requested === 'bounded') {
|
|
101
|
+
qualification = boundedEvidence ? 'qualified' : 'invalid-bounded-scope-claim';
|
|
102
|
+
materialization = boundedEvidence ? 'bounded' : 'partial';
|
|
103
|
+
}
|
|
104
|
+
if (qualification === 'invalid-completeness-claim' && findings) findings.push(finding('error', 'portable.handoff-material.workspace.complete-unproven', 'Workspace materialization claimed complete without qualified completeness evidence for the declared workspace boundary.', { workspaceId: item.id || item.workspaceId || `workspace-${index}` }));
|
|
105
|
+
if (qualification === 'invalid-bounded-scope-claim' && findings) findings.push(finding('error', 'portable.handoff-material.workspace.bounded-unproven', 'Workspace materialization claimed bounded without qualified exact representation-entry-set scope evidence.', { workspaceId: item.id || item.workspaceId || `workspace-${index}` }));
|
|
106
|
+
return deepFreeze({
|
|
107
|
+
id: String(item.id || item.workspaceId || `workspace-${index}`),
|
|
108
|
+
title: String(item.title || item.name || item.workspaceTitle || item.id || item.workspaceId || `workspace-${index}`),
|
|
109
|
+
source: Object.freeze({ ...(item.source || {}) }),
|
|
110
|
+
materialization,
|
|
111
|
+
qualification,
|
|
112
|
+
completenessEvidence: Object.freeze({ ...(item.completenessEvidence || item.completeEvidence || {}) }),
|
|
113
|
+
scopeEvidence: Object.freeze({ ...(item.scopeEvidence || {}) }),
|
|
114
|
+
includedEntries: Object.freeze((item.includedEntries || item.entries || []).map(normalizeIncludedEntry))
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function workspaceMaterializationCorrelationEvidence(item = {}, prequalified = null) {
|
|
119
|
+
const qualified = prequalified || qualifyWorkspaceMaterialization(item);
|
|
120
|
+
return deepFreeze(sortJson({
|
|
121
|
+
schema: 'tiinex.portable.handoff-workspace-transport-correlation-evidence.v1',
|
|
122
|
+
declared: {
|
|
123
|
+
id: String(item.id || ''),
|
|
124
|
+
workspaceId: String(item.workspaceId || ''),
|
|
125
|
+
requestedMaterialization: String(item.state || item.materialization || 'partial')
|
|
126
|
+
},
|
|
127
|
+
source: serializable(item.source || {}),
|
|
128
|
+
completenessEvidence: serializable(item.completenessEvidence || item.completeEvidence || {}),
|
|
129
|
+
scopeEvidence: serializable(item.scopeEvidence || {}),
|
|
130
|
+
carrierEntries: (item.entries || []).map((entry) => carrierCorrelationEntry(entry)),
|
|
131
|
+
qualifiedTruth: {
|
|
132
|
+
materialization: String(qualified.materialization || 'partial'),
|
|
133
|
+
qualification: String(qualified.qualification || ''),
|
|
134
|
+
completenessEvidence: serializable(qualified.completenessEvidence || {}),
|
|
135
|
+
scopeEvidence: serializable(qualified.scopeEvidence || {}),
|
|
136
|
+
includedEntries: (qualified.includedEntries || []).map(normalizeIncludedEntry)
|
|
137
|
+
}
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function workspaceMaterializationCorrelationKey(item = {}) {
|
|
142
|
+
return workspaceMaterializationCorrelationKeyFromEvidence(workspaceMaterializationCorrelationEvidence(item));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function workspaceMaterializationCorrelationKeyFromEvidence(evidence = {}) {
|
|
146
|
+
return JSON.stringify(sortJson(serializable(evidence)));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function qualifyWorkspaceMaterializationCorrelationEntry(item = {}) {
|
|
150
|
+
const evidence = item?.transportCorrelationEvidence
|
|
151
|
+
? deepFreeze(sortJson(serializable(item.transportCorrelationEvidence)))
|
|
152
|
+
: workspaceMaterializationCorrelationEvidence(item);
|
|
153
|
+
const key = String(item?.transportCorrelationKey || '');
|
|
154
|
+
const expectedKey = workspaceMaterializationCorrelationKeyFromEvidence(evidence);
|
|
155
|
+
const findings = [];
|
|
156
|
+
if (!key) findings.push('transport-correlation-key-missing');
|
|
157
|
+
else if (key !== expectedKey) findings.push('transport-correlation-key-stale');
|
|
158
|
+
const qualifiedTruth = evidence.qualifiedTruth || {};
|
|
159
|
+
if (stableJson(item.source || {}) !== stableJson(evidence.source || {})) findings.push('transport-correlation-source-mismatch');
|
|
160
|
+
if (String(item.materialization || '') !== String(qualifiedTruth.materialization || '')) findings.push('transport-correlation-materialization-mismatch');
|
|
161
|
+
if (String(item.qualification || '') !== String(qualifiedTruth.qualification || '')) findings.push('transport-correlation-qualification-mismatch');
|
|
162
|
+
if (stableJson(item.completenessEvidence || {}) !== stableJson(qualifiedTruth.completenessEvidence || {})) findings.push('transport-correlation-completeness-evidence-mismatch');
|
|
163
|
+
if (stableJson(item.scopeEvidence || {}) !== stableJson(qualifiedTruth.scopeEvidence || {})) findings.push('transport-correlation-scope-evidence-mismatch');
|
|
164
|
+
if (stableJson(item.includedEntries || []) !== stableJson(qualifiedTruth.includedEntries || [])) findings.push('transport-correlation-included-entries-mismatch');
|
|
165
|
+
return Object.freeze({ state: findings.length ? 'invalid' : 'qualified', key, expectedKey, evidence, findings: Object.freeze(findings) });
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function carrierCorrelationEntry(entry = {}) {
|
|
169
|
+
const data = packageFileBytes(entry);
|
|
170
|
+
return Object.freeze({
|
|
171
|
+
path: String(entry.path || ''),
|
|
172
|
+
requestedPackagePath: String(entry.packagePath || ''),
|
|
173
|
+
referenceTarget: String(entry.referenceTarget || ''),
|
|
174
|
+
mediaType: String(entry.mediaType || entry.type || ''),
|
|
175
|
+
bytes: data.byteLength,
|
|
176
|
+
sha256: sha256Hex(data)
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function normalizeIncludedEntry(entry = {}) {
|
|
181
|
+
return Object.freeze({ path: String(entry.path || ''), sha256: String(entry.sha256 || ''), bytes: Number(entry.bytes || 0), referenceTarget: String(entry.referenceTarget || '') });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function stableJson(value) { return JSON.stringify(sortJson(serializable(value))); }
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
function serializable(value = {}) {
|
|
188
|
+
if (Array.isArray(value)) return value.map(serializable);
|
|
189
|
+
if (!value || typeof value !== 'object') return value;
|
|
190
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return undefined;
|
|
191
|
+
return Object.fromEntries(Object.entries(value).flatMap(([key, item]) => {
|
|
192
|
+
if (typeof item === 'function' || typeof item === 'undefined') return [];
|
|
193
|
+
const normalized = serializable(item);
|
|
194
|
+
return typeof normalized === 'undefined' ? [] : [[key, normalized]];
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
function sortJson(value) {
|
|
198
|
+
if (Array.isArray(value)) return value.map(sortJson);
|
|
199
|
+
if (!value || typeof value !== 'object') return value;
|
|
200
|
+
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, sortJson(value[key])]));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function finding(severity, code, message, extra = {}) { return Object.freeze({ severity, code, message, ...extra }); }
|
|
204
|
+
function deepFreeze(value) { if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value; if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return value; for (const child of Object.values(value)) deepFreeze(child); return Object.freeze(value); }
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function qualifyHandoffMaterialClosurePlanReadiness(plan = {}) {
|
|
2
|
+
const blockingRequirements = [
|
|
3
|
+
...(plan.requirements?.required || []),
|
|
4
|
+
...(plan.requirements?.endpointRoles || []),
|
|
5
|
+
...(plan.requirements?.participantRoles || []),
|
|
6
|
+
...(plan.requirements?.dependencies || [])
|
|
7
|
+
];
|
|
8
|
+
const requiredBlockers = Object.freeze(blockingRequirements
|
|
9
|
+
.filter((entry) => ['unresolved', 'ambiguous', 'integrity-conflict'].includes(String(entry?.disposition || '')))
|
|
10
|
+
.map((entry) => Object.freeze({ requirementId: String(entry?.requirementId || ''), disposition: String(entry?.disposition || '') })));
|
|
11
|
+
const workspaceBlockers = Object.freeze((plan.workspaceMaterializations || [])
|
|
12
|
+
.filter((entry) => String(entry?.qualification || '') !== 'qualified')
|
|
13
|
+
.map((entry) => Object.freeze({ id: String(entry?.id || ''), materialization: String(entry?.materialization || 'partial'), qualification: String(entry?.qualification || 'unresolved') })));
|
|
14
|
+
const expectedRequiredClosureReady = requiredBlockers.length === 0 && workspaceBlockers.length === 0;
|
|
15
|
+
const expectedStatus = expectedRequiredClosureReady ? 'ready' : 'blocked';
|
|
16
|
+
const declaredRequiredClosureReady = Boolean(plan.requiredClosureReady);
|
|
17
|
+
const declaredStatus = String(plan.status || 'blocked');
|
|
18
|
+
const findings = [];
|
|
19
|
+
if (declaredRequiredClosureReady !== expectedRequiredClosureReady) findings.push('required-closure-ready-contradictory');
|
|
20
|
+
if (declaredStatus !== expectedStatus) findings.push('plan-status-contradictory');
|
|
21
|
+
return deepFreeze({
|
|
22
|
+
state: findings.length ? 'invalid' : 'qualified',
|
|
23
|
+
declaredStatus,
|
|
24
|
+
declaredRequiredClosureReady,
|
|
25
|
+
expectedStatus,
|
|
26
|
+
expectedRequiredClosureReady,
|
|
27
|
+
blockers: Object.freeze({ required: requiredBlockers, workspaces: workspaceBlockers }),
|
|
28
|
+
findings: Object.freeze(findings)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function deepFreeze(value) {
|
|
33
|
+
if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value;
|
|
34
|
+
for (const child of Object.values(value)) deepFreeze(child);
|
|
35
|
+
return Object.freeze(value);
|
|
36
|
+
}
|