@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,193 @@
|
|
|
1
|
+
import { qualifyHandoffCarrierWorkspaces, selectHandoffCarrierDefaultWorkspace, handoffCarrierWorkspaceForRoute, projectHandoffCarrierWorkspace, findProjectedHandoffCarrierWorkspace } from './carrierProjection.workspaces.js';
|
|
2
|
+
import { HANDOFF_HUMAN_OUTPUT_PRESENTATION, HANDOFF_NORMAL_EMISSION_BOUNDARY } from './humanOutputPresentation.js';
|
|
3
|
+
import { normalizeHandoffCarrierLineage } from './carrierLineage.js';
|
|
4
|
+
import { buildHandoffWorkspaceByteProvider } from './workspaceByteProvider.js';
|
|
5
|
+
import { qualifyRoute } from './carrierProjection.routeQualification.js';
|
|
6
|
+
import { deepFreeze, findFile, normalizeWorkspacePath, parseJsonFile } from './carrierProjection.shared.js';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export const HANDOFF_CARRIER_PROJECTION_SCHEMA_ID = 'tiinex.portable.handoff-carrier-projection.v1';
|
|
10
|
+
export const HANDOFF_CARRIER_PROJECTION_PATH = 'tiinex.package/handoff-carrier.json';
|
|
11
|
+
export const HANDOFF_HUMAN_OUTPUT_SCHEMA_ID = 'tiinex.portable.handoff-human-output.v1';
|
|
12
|
+
|
|
13
|
+
const BOUNDARY = 'Disposable human carrier/output projection derived from qualified package/workspace Handoff bytes. Filename, dimension, route labels, transport text, and collision suffix carry no Parent, assignment, acceptance, completion, package-identity, or source authority.';
|
|
14
|
+
|
|
15
|
+
export function buildHandoffCarrierProjection(input = {}) {
|
|
16
|
+
const bundle = input.bundle || {};
|
|
17
|
+
const descriptor = input.descriptor || parseJsonFile(findFile(bundle, 'tiinex.package/handoff-closure.json')) || bundle.handoffClosure || {};
|
|
18
|
+
const byteProvider = input.workspaceByteProvider || buildHandoffWorkspaceByteProvider(bundle, descriptor);
|
|
19
|
+
const workspaces = qualifyHandoffCarrierWorkspaces(bundle, descriptor, byteProvider);
|
|
20
|
+
const defaultWorkspace = selectHandoffCarrierDefaultWorkspace(bundle, workspaces);
|
|
21
|
+
const routeSpecs = normalizeRouteSpecs(input.routes || input.handoffRoutes || [], descriptor, defaultWorkspace);
|
|
22
|
+
const lineage = normalizeHandoffCarrierLineage(input.carrierLineage || input.lineage || null);
|
|
23
|
+
const shared = routeSpecs.length > 1;
|
|
24
|
+
const routes = routeSpecs.map((spec) => qualifyRoute(bundle, descriptor, byteProvider, handoffCarrierWorkspaceForRoute(workspaces, spec.workspaceId), spec, { enforceRequiredClosure: shared, carrierDimension: lineage.dimension }));
|
|
25
|
+
const qualifiedRoutes = routes.filter((route) => route.state === 'qualified');
|
|
26
|
+
const mode = routes.length > 1 ? 'shared' : 'single';
|
|
27
|
+
const findings = [];
|
|
28
|
+
if (!workspaces.length) findings.push(finding('error', 'portable.handoff-carrier.workspaces.missing', 'Carrier projection requires at least one package workspace materialization.'));
|
|
29
|
+
for (const workspace of workspaces) if (workspace.state !== 'qualified') findings.push(finding('error', `portable.handoff-carrier.workspace.${workspace.state}`, 'Carrier projection workspace is not uniquely qualified against package truth.', { workspaceId: workspace.id || '' }));
|
|
30
|
+
if (!routes.length) findings.push(finding('error', 'portable.handoff-carrier.routes.missing', 'Carrier projection requires at least one controlling Handoff route.'));
|
|
31
|
+
for (const route of routes) {
|
|
32
|
+
if (route.state !== 'qualified') findings.push(finding('error', `portable.handoff-carrier.route.${route.state}`, 'Carrier projection route is not independently qualified against package truth.', { path: route.workspaceRelativePath || '', reasons: route.reasons || [] }));
|
|
33
|
+
for (const item of route.conformance?.findings || []) findings.push(finding(item.severity || 'error', item.code || 'portable.handoff-carrier.route.conformance', item.message || 'Selected Handoff conformance failed.', { path: route.workspaceRelativePath || '' }));
|
|
34
|
+
}
|
|
35
|
+
if (qualifiedRoutes.length !== routes.length) findings.push(finding('error', 'portable.handoff-carrier.routes.unqualified', 'One or more advertised Handoff routes are unqualified; shared human routing must fail closed.'));
|
|
36
|
+
const status = findings.some((item) => item.severity === 'error') ? 'blocked' : 'ready';
|
|
37
|
+
return deepFreeze({
|
|
38
|
+
schema: HANDOFF_CARRIER_PROJECTION_SCHEMA_ID,
|
|
39
|
+
version: 1,
|
|
40
|
+
boundary: BOUNDARY,
|
|
41
|
+
status,
|
|
42
|
+
mode,
|
|
43
|
+
lineage,
|
|
44
|
+
workspaces: Object.freeze(workspaces.map(projectHandoffCarrierWorkspace)),
|
|
45
|
+
workspace: defaultWorkspace ? projectHandoffCarrierWorkspace(defaultWorkspace) : Object.freeze({ id: '', title: '', slug: '', qualification: 'unresolved' }),
|
|
46
|
+
selection: Object.freeze({ policy: mode === 'shared' ? 'explicit-qualified-route-required' : 'implicit-single-qualified-route', qualifiedRouteCount: qualifiedRoutes.length }),
|
|
47
|
+
routes: Object.freeze(routes),
|
|
48
|
+
authority: Object.freeze({ semanticAuthority: 'none', filenameAuthority: false, dimensionalParentAuthority: false, routeSelectionAuthority: 'package-qualified-route-membership-only' }),
|
|
49
|
+
findings: Object.freeze(findings)
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function inspectHandoffCarrierProjection(bundle = {}, options = {}) {
|
|
54
|
+
const findings = [];
|
|
55
|
+
const file = findFile(bundle, HANDOFF_CARRIER_PROJECTION_PATH);
|
|
56
|
+
const projection = parseJsonFile(file);
|
|
57
|
+
if (!projection) findings.push(finding('error', 'portable.handoff-carrier.missing', 'Handoff package is missing a readable carrier projection.'));
|
|
58
|
+
if (projection && projection.schema !== HANDOFF_CARRIER_PROJECTION_SCHEMA_ID) findings.push(finding('error', 'portable.handoff-carrier.schema.invalid', 'Handoff carrier projection schema/version is unsupported.'));
|
|
59
|
+
if (projection && projection.boundary !== BOUNDARY) findings.push(finding('error', 'portable.handoff-carrier.boundary.invalid', 'Handoff carrier projection lost its disposable non-authoritative boundary.'));
|
|
60
|
+
if (projection) {
|
|
61
|
+
const expected = buildHandoffCarrierProjection({ bundle, workspaceByteProvider: options.workspaceByteProvider || null, carrierLineage: projection.lineage || null, routes: (projection.routes || []).map((route) => ({ workspaceId: route.workspaceId, path: route.workspaceRelativePath, purpose: route.purpose, participantRoles: route.participantRoleSpecs || [] })) });
|
|
62
|
+
for (const field of ['status', 'mode', 'lineage', 'workspaces', 'workspace', 'selection', 'routes', 'authority']) {
|
|
63
|
+
if (stableJson(expected[field]) !== stableJson(projection[field])) findings.push(finding('error', `portable.handoff-carrier.${field}.mismatch`, `Handoff carrier ${field} diverges from current package/workspace truth.`));
|
|
64
|
+
}
|
|
65
|
+
if (projection.authority?.semanticAuthority !== 'none' || projection.authority?.filenameAuthority !== false || projection.authority?.dimensionalParentAuthority !== false) findings.push(finding('error', 'portable.handoff-carrier.authority.promotion', 'Handoff carrier projection promotes human transport metadata into semantic authority.'));
|
|
66
|
+
}
|
|
67
|
+
return deepFreeze({ schema: 'tiinex.portable.handoff-carrier-projection.inspection.v1', status: findings.some((item) => item.severity === 'error') ? 'invalid' : 'valid', projection, findings: Object.freeze(findings), findingSummary: Object.freeze({ findings: findings.length, errors: findings.filter((item) => item.severity === 'error').length }) });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function projectHandoffHumanOutput(input = {}) {
|
|
71
|
+
const projection = input.projection || input.carrierProjection || {};
|
|
72
|
+
const findings = [];
|
|
73
|
+
if (projection.schema !== HANDOFF_CARRIER_PROJECTION_SCHEMA_ID || projection.status !== 'ready') findings.push(finding('error', 'portable.handoff-human-output.projection.unready', 'Human output requires a ready qualified Handoff carrier projection.'));
|
|
74
|
+
const selected = selectRoute(projection, input.route || input.routePath || input.routeId || '');
|
|
75
|
+
if (selected.state !== 'qualified') findings.push(finding('error', `portable.handoff-human-output.route.${selected.state}`, selected.state === 'selection-required' ? 'Shared carrier output requires explicit selection of one qualified Handoff route.' : 'Requested Handoff route is not qualified by the carrier projection.', { selector: String(input.route || input.routePath || input.routeId || '') }));
|
|
76
|
+
const instance = normalizeInstance(input.collisionInstance || input.instance || 1);
|
|
77
|
+
const filename = selected.route ? carrierFilenameForInstance(projectedOuterFilename(projection, selected.route), instance) : '';
|
|
78
|
+
const routeWorkspace = selected.route ? findProjectedHandoffCarrierWorkspace(projection, selected.route.workspaceId) : null;
|
|
79
|
+
const transportText = selected.route ? transportTextForRoute(routeWorkspace || projection.workspace || {}, selected.route) : '';
|
|
80
|
+
const sharedRouting = projectSharedRouting(projection, instance);
|
|
81
|
+
const status = findings.some((item) => item.severity === 'error') ? (selected.state === 'selection-required' ? 'selection-required' : 'blocked') : 'ready';
|
|
82
|
+
return deepFreeze({
|
|
83
|
+
schema: HANDOFF_HUMAN_OUTPUT_SCHEMA_ID,
|
|
84
|
+
status,
|
|
85
|
+
primary: selected.route ? Object.freeze({ kind: 'handoff-package', filename, dimension: String(projection.lineage?.dimension || selected.route.dimension || ''), parentDimension: String(projection.lineage?.parentDimension || ''), checkpointKind: String(projection.lineage?.checkpointKind || ''), routeId: selected.route.id, workspaceId: selected.route.workspaceId, workspaceRelativeHandoffPath: selected.route.workspaceRelativePath, collisionInstance: instance, singleHumanTransportChoice: true }) : null,
|
|
86
|
+
normalInlineRouting: selected.route ? Object.freeze({ kind: 'transport-text', content: transportText, normalEmission: true, requiredForHumanCompletion: true, placement: 'adjacent-to-primary', authority: 'none' }) : null,
|
|
87
|
+
sharedRouting,
|
|
88
|
+
presentation: HANDOFF_HUMAN_OUTPUT_PRESENTATION,
|
|
89
|
+
normalEmissionBoundary: HANDOFF_NORMAL_EMISSION_BOUNDARY,
|
|
90
|
+
fallbackTransportText: selected.route ? Object.freeze({ supported: true, filename: transportSidecarFilename(filename), content: transportText, normalEmission: false, requiredForHumanCompletion: false, authority: 'none' }) : null,
|
|
91
|
+
selectedRoute: selected.route || null,
|
|
92
|
+
findings: Object.freeze(findings),
|
|
93
|
+
boundary: 'Human-facing output projection only. Normal completion is exactly the sole primary package plus the adjacent exact routing content in a copyable host surface. Presentation wrappers carry no semantic authority. Internal humanOutput JSON, helper artifacts, semantic work-summary prose, manually reconstructed routing, duplicate normal file choices, and optional transport-text sidecars are outside normal emission unless explicitly requested.'
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function projectHandoffCarrierOutputFromPackage(input = {}) {
|
|
98
|
+
const bundle = input.bundle || input;
|
|
99
|
+
const inspection = inspectHandoffCarrierProjection(bundle);
|
|
100
|
+
const humanOutput = projectHandoffHumanOutput({ projection: inspection.projection || {}, route: input.route || input.routePath || input.routeId || '', collisionInstance: input.collisionInstance || input.instance || 1 });
|
|
101
|
+
const findings = Object.freeze([...(inspection.findings || []), ...(humanOutput.findings || [])]);
|
|
102
|
+
return deepFreeze({ schema: 'tiinex.portable.handoff-carrier-output-projection.v1', status: inspection.status === 'valid' && humanOutput.status === 'ready' ? 'ready' : humanOutput.status === 'selection-required' ? 'selection-required' : 'blocked', carrierInspection: inspection, humanOutput, findings, boundary: 'Read-only regeneration of carrier filename and minimal transport text from package-qualified route truth.' });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function carrierFilenameForInstance(filename = '', instance = 1) {
|
|
106
|
+
const value = String(filename || 'handoff.handoff-package.zip');
|
|
107
|
+
const number = normalizeInstance(instance);
|
|
108
|
+
if (number <= 1) return value;
|
|
109
|
+
const suffix = '.handoff-package.zip';
|
|
110
|
+
return value.toLowerCase().endsWith(suffix) ? `${value.slice(0, -suffix.length)}--${number}${suffix}` : `${value}--${number}`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
function projectSharedRouting(projection = {}, instance = 1) {
|
|
116
|
+
if (String(projection.mode || '') !== 'shared') return null;
|
|
117
|
+
const routes = (projection.routes || []).filter((route) => route.state === 'qualified');
|
|
118
|
+
if (!routes.length) return null;
|
|
119
|
+
const filename = carrierFilenameForInstance(projectedOuterFilename(projection, routes[0]), instance);
|
|
120
|
+
return Object.freeze({
|
|
121
|
+
mode: 'one-shared-package-many-exact-route-texts',
|
|
122
|
+
primary: Object.freeze({ kind: 'handoff-package', filename }),
|
|
123
|
+
routes: Object.freeze(routes.map((route) => {
|
|
124
|
+
const workspace = findProjectedHandoffCarrierWorkspace(projection, route.workspaceId) || projection.workspace || {};
|
|
125
|
+
return Object.freeze({
|
|
126
|
+
routeId: String(route.id || ''),
|
|
127
|
+
workspaceId: String(route.workspaceId || ''),
|
|
128
|
+
workspaceRelativeHandoffPath: String(route.workspaceRelativePath || ''),
|
|
129
|
+
transportText: transportTextForRoute(workspace, route),
|
|
130
|
+
authority: 'none'
|
|
131
|
+
});
|
|
132
|
+
})),
|
|
133
|
+
selectionAuthority: 'exact-qualified-route-only',
|
|
134
|
+
siblingInference: false,
|
|
135
|
+
readOnly: true
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function projectedOuterFilename(projection = {}, selectedRoute = {}) {
|
|
140
|
+
if (String(projection.mode || '') !== 'shared') return String(selectedRoute.projectedFilename || '');
|
|
141
|
+
const routes = (projection.routes || []).filter((route) => route.state === 'qualified');
|
|
142
|
+
const recipients = [...new Set(routes.map((route) => String(route.parties?.to || '').trim()).filter(Boolean))];
|
|
143
|
+
const senders = [...new Set(routes.map((route) => String(route.parties?.from || '').trim()).filter(Boolean))];
|
|
144
|
+
const workspace = projection.workspace || findProjectedHandoffCarrierWorkspace(projection, selectedRoute.workspaceId) || {};
|
|
145
|
+
const dimension = String(projection.lineage?.dimension || selectedRoute.dimension || '').trim();
|
|
146
|
+
if (senders.length !== 1 || !recipients.length || !workspace.slug || !dimension) return String(selectedRoute.projectedFilename || '');
|
|
147
|
+
const recipientSegment = recipients.map(slug).filter(Boolean).join('-and-');
|
|
148
|
+
return `${slug(workspace.slug)}-${slug(dimension)}-${slug(senders[0])}-to-${recipientSegment}.handoff-package.zip`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function slug(value = '') {
|
|
152
|
+
return String(value || '').trim().toLowerCase().normalize('NFKD').replace(/[̀-ͯ]/g, '').replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 120);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function normalizeRouteSpecs(value, descriptor, defaultWorkspace = null) {
|
|
156
|
+
const supplied = Array.isArray(value) ? value : value ? [value] : [];
|
|
157
|
+
const fallback = normalizeWorkspacePath(descriptor.handoff?.path || descriptor.handoff?.id || '');
|
|
158
|
+
const defaultWorkspaceId = String(defaultWorkspace?.id || '');
|
|
159
|
+
const map = new Map();
|
|
160
|
+
for (const raw of supplied.length ? supplied : [Object.freeze({ workspaceId: defaultWorkspaceId, path: fallback })]) {
|
|
161
|
+
const spec = typeof raw === 'string' ? { workspaceId: defaultWorkspaceId, path: raw } : (raw || {});
|
|
162
|
+
const path = normalizeWorkspacePath(spec.path || spec.workspaceRelativePath || '');
|
|
163
|
+
const workspaceId = String(spec.workspaceId || spec.workspace || defaultWorkspaceId || '');
|
|
164
|
+
const key = `${workspaceId}\u0000${path}`;
|
|
165
|
+
if (path && !map.has(key)) map.set(key, Object.freeze({ workspaceId, path, purpose: String(spec.purpose || ''), participantRoles: Object.freeze([...(spec.participantRoles || spec.roles || [])].map((entry) => typeof entry === 'string' ? entry : Object.freeze({ ...(entry || {}) }))) }));
|
|
166
|
+
}
|
|
167
|
+
return [...map.values()].sort((a, b) => a.workspaceId.localeCompare(b.workspaceId) || a.path.localeCompare(b.path));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function selectRoute(projection, selector = '') {
|
|
171
|
+
const routes = (projection.routes || []).filter((route) => route.state === 'qualified');
|
|
172
|
+
const requested = String(selector || '').trim();
|
|
173
|
+
if (!requested) {
|
|
174
|
+
if (projection.mode === 'shared' || routes.length > 1) return Object.freeze({ state: 'selection-required', route: null });
|
|
175
|
+
return routes.length === 1 ? Object.freeze({ state: 'qualified', route: routes[0] }) : Object.freeze({ state: 'unresolved', route: null });
|
|
176
|
+
}
|
|
177
|
+
const normalized = normalizeWorkspacePath(requested);
|
|
178
|
+
const matches = routes.filter((route) => route.id === requested || `${route.workspaceId}:${normalizeWorkspacePath(route.workspaceRelativePath)}` === requested || normalizeWorkspacePath(route.workspaceRelativePath) === normalized);
|
|
179
|
+
return matches.length === 1 ? Object.freeze({ state: 'qualified', route: matches[0] }) : Object.freeze({ state: matches.length > 1 ? 'ambiguous' : 'unresolved', route: null });
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function transportTextForRoute(workspace = {}, route = {}) {
|
|
183
|
+
const title = String(workspace.title || workspace.id || 'workspace');
|
|
184
|
+
return `Handoff package attached.\n\nWorkspace: ${title}\nContinue from:\n${route.workspaceRelativePath}\n`;
|
|
185
|
+
}
|
|
186
|
+
function transportSidecarFilename(filename = '') {
|
|
187
|
+
const suffix = '.handoff-package.zip';
|
|
188
|
+
return filename.toLowerCase().endsWith(suffix) ? `${filename.slice(0, -suffix.length)}.transport.txt` : `${filename}.transport.txt`;
|
|
189
|
+
}
|
|
190
|
+
function normalizeInstance(value) { const n = Number.parseInt(value, 10); return Number.isFinite(n) && n > 1 ? n : 1; }
|
|
191
|
+
function stableJson(value) { return JSON.stringify(sortJson(value)); }
|
|
192
|
+
function sortJson(value) { if (Array.isArray(value)) return value.map(sortJson); if (!value || typeof value !== 'object') return value; return Object.fromEntries(Object.keys(value).sort().map((key) => [key, sortJson(value[key])])); }
|
|
193
|
+
function finding(severity, code, message, extra = {}) { return Object.freeze({ severity, code, message, ...extra }); }
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { packageFileBytes, sha256Hex } from '../../../export/package.bytes.js';
|
|
2
|
+
import { validatedC14nV2PrimarySelfDigest } from '../../../integrity/integrity.c14nV2.js';
|
|
3
|
+
import { projectHandoffMaterialRequirements, projectParticipantRoleRequirements } from './materialClosure.requirements.js';
|
|
4
|
+
import { qualifySelectedHandoffArtifact } from './routeArtifactConformance.js';
|
|
5
|
+
import { listHandoffWorkspaceEntries, resolveHandoffWorkspaceEntry } from './workspaceByteProvider.js';
|
|
6
|
+
import { parseWorkspaceQualifiedReference, SHARED_ROUTE_REQUIRED_CONTEXT_BOUNDARY } from './workspaceQualifiedReference.js';
|
|
7
|
+
import { decodeUtf8, deepFreeze, findFile, normalizeWorkspacePath } from './carrierProjection.shared.js';
|
|
8
|
+
|
|
9
|
+
export function qualifyRoute(bundle, descriptor, byteProvider, workspace, spec = {}, options = {}) {
|
|
10
|
+
const routePath = normalizeWorkspacePath(spec.path || spec.workspaceRelativePath || '');
|
|
11
|
+
const reasons = [];
|
|
12
|
+
if (workspace.state !== 'qualified') reasons.push(`workspace-${workspace.state || 'unresolved'}`);
|
|
13
|
+
if (!routePath || !isWorkspaceRelativeArtifactPath(routePath)) reasons.push('workspace-relative-trace-path-required');
|
|
14
|
+
const resolution = routePath && workspace.id ? resolveHandoffWorkspaceEntry(byteProvider, workspace.id, routePath) : null;
|
|
15
|
+
if (!resolution || resolution.state !== 'qualified') reasons.push(resolution?.reason || 'workspace-entry-missing');
|
|
16
|
+
const data = resolution?.state === 'qualified' ? packageFileBytes({ data: resolution.data }) : new Uint8Array();
|
|
17
|
+
if (resolution?.state === 'qualified' && String(resolution.sha256 || '') !== sha256Hex(data)) reasons.push('workspace-byte-digest-mismatch');
|
|
18
|
+
const markdown = data.byteLength ? decodeUtf8(data) : '';
|
|
19
|
+
const conformance = markdown ? qualifySelectedHandoffArtifact({ markdown, resolveParent: ({ parent, targetEntry }) => resolveRouteParent(bundle, descriptor, byteProvider, workspace, routePath, parent, targetEntry) }) : null;
|
|
20
|
+
if (!conformance || conformance.status !== 'qualified') reasons.push('handoff-conformance-unqualified');
|
|
21
|
+
const participantRoleSpecs = Object.freeze([...(spec.participantRoles || spec.roles || [])].map((entry) => typeof entry === 'string' ? entry : Object.freeze({ ...(entry || {}) })));
|
|
22
|
+
const baseRequirements = projectHandoffMaterialRequirements({ path: routePath, markdown });
|
|
23
|
+
const participantRoles = projectParticipantRoleRequirements(participantRoleSpecs, { workspaceId: String(workspace.id || spec.workspaceId || ''), routePath });
|
|
24
|
+
const materialRequirements = deepFreeze({ ...baseRequirements, participantRoles, counts: Object.freeze({ ...(baseRequirements.counts || {}), participantRoles: participantRoles.length }) });
|
|
25
|
+
const requiredClosure = qualifyRouteRequiredClosure(bundle, descriptor, byteProvider, workspace, routePath, materialRequirements);
|
|
26
|
+
if (options.enforceRequiredClosure && requiredClosure.state !== 'qualified') reasons.push('required-context-closure-unqualified');
|
|
27
|
+
const parties = parseHandoffParties(markdown);
|
|
28
|
+
if (!parties.from) reasons.push('from-unresolved');
|
|
29
|
+
if (!parties.to) reasons.push('to-unresolved');
|
|
30
|
+
const dimension = String(options.carrierDimension || '').trim();
|
|
31
|
+
if (!dimension) reasons.push('dimension-unresolved');
|
|
32
|
+
const purpose = slug(spec.purpose || '');
|
|
33
|
+
const projectedFilename = !reasons.length ? carrierFilename(workspace.slug, dimension, parties.from, parties.to) : '';
|
|
34
|
+
const providerMode = String(resolution?.providerMode || '');
|
|
35
|
+
const packagePath = String(resolution?.packagePath || '');
|
|
36
|
+
const pointerTarget = providerMode === 'archive'
|
|
37
|
+
? `${packagePath}#tiinex-workspace-entry=${encodeURIComponent(routePath)}`
|
|
38
|
+
: packagePath;
|
|
39
|
+
return deepFreeze({
|
|
40
|
+
id: routePath && workspace.id ? `handoff-route:${workspace.id}:${routePath}` : '',
|
|
41
|
+
workspaceId: String(workspace.id || spec.workspaceId || ''),
|
|
42
|
+
state: reasons.length ? 'blocked' : 'qualified',
|
|
43
|
+
workspaceRelativePath: routePath,
|
|
44
|
+
packagePath,
|
|
45
|
+
...(providerMode === 'archive' ? { providerMode, archivePackagePath: String(resolution?.archivePackagePath || packagePath), pointerTarget } : {}),
|
|
46
|
+
sha256: data.byteLength ? sha256Hex(data) : '',
|
|
47
|
+
dimension,
|
|
48
|
+
parties: Object.freeze({ from: parties.from, to: parties.to, fromSlug: slug(parties.from), toSlug: slug(parties.to) }),
|
|
49
|
+
purpose,
|
|
50
|
+
projectedFilename,
|
|
51
|
+
conformance,
|
|
52
|
+
materialRequirements,
|
|
53
|
+
participantRoles,
|
|
54
|
+
participantRoleSpecs,
|
|
55
|
+
requiredClosure,
|
|
56
|
+
reasons: Object.freeze(reasons),
|
|
57
|
+
authority: Object.freeze({ artifactPartiesAuthoritative: true, dimensionSemanticAuthority: false, filenameSemanticAuthority: false })
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function qualifyRouteRequiredClosure(bundle, descriptor, byteProvider, workspace, routePath, requirements) {
|
|
62
|
+
const required=(requirements.required||[]).map((requirement)=>qualifyRequiredRequirement(bundle,descriptor,byteProvider,workspace,routePath,requirement));
|
|
63
|
+
const qualified=required.filter((entry)=>entry.state==='qualified').length;
|
|
64
|
+
return deepFreeze({state:qualified===required.length?'qualified':'blocked',requiredCount:required.length,qualifiedCount:qualified,requirements:Object.freeze(required),boundary:SHARED_ROUTE_REQUIRED_CONTEXT_BOUNDARY});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function qualifyRequiredRequirement(bundle, descriptor, byteProvider, workspace, routePath, requirement = {}) {
|
|
68
|
+
const target=String(requirement.reference?.target||'').trim(), requirementId=String(requirement.id||'').trim(), reasons=[];
|
|
69
|
+
let resolution=null;
|
|
70
|
+
if (!target||target.startsWith('#')) { resolution=resolveDescriptorMaterial(bundle,descriptor,byteProvider,target,requirementId,workspace.id,routePath); if(!resolution) reasons.push('exact-required-material-reference-or-binding-unresolved'); }
|
|
71
|
+
const qualified=parseWorkspaceQualifiedReference(target);
|
|
72
|
+
if (!resolution&&!reasons.length&&qualified) resolution=resolveWorkspaceRequiredMaterial(byteProvider,{id:qualified.workspaceId},qualified.path);
|
|
73
|
+
if (!resolution&&!reasons.length&&!qualified&&!isExternalReference(target)) { const resolvedPath=resolveWorkspaceReference(routePath,target); if(!resolvedPath) reasons.push('workspace-reference-outside-or-invalid'); else resolution=resolveWorkspaceRequiredMaterial(byteProvider,workspace,resolvedPath); }
|
|
74
|
+
if (!resolution&&!reasons.length) resolution=resolveDescriptorMaterial(bundle,descriptor,byteProvider,target,requirementId,workspace.id,routePath);
|
|
75
|
+
if (!resolution&&!reasons.length) reasons.push('required-material-not-carried');
|
|
76
|
+
if (resolution?.state!=='qualified'&&resolution?.reason) reasons.push(resolution.reason);
|
|
77
|
+
return deepFreeze({requirementId:String(requirement.id||''),name:String(requirement.name||''),referenceTarget:target,state:!reasons.length&&resolution?.state==='qualified'?'qualified':'blocked',resolution:resolution?.state==='qualified'?resolution:null,reasons:Object.freeze([...new Set(reasons)])});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function resolveWorkspaceRequiredMaterial(byteProvider, workspace, resolvedPath) {
|
|
81
|
+
const resolution = resolveHandoffWorkspaceEntry(byteProvider, workspace.id, resolvedPath);
|
|
82
|
+
if (resolution.state !== 'qualified') {
|
|
83
|
+
const reason = resolution.state === 'ambiguous' ? 'required-workspace-entry-ambiguous' : resolution.state === 'unresolved' ? 'required-workspace-entry-missing' : (resolution.reason || 'required-workspace-entry-missing');
|
|
84
|
+
return Object.freeze({ state: 'blocked', reason });
|
|
85
|
+
}
|
|
86
|
+
const data = packageFileBytes({ data: resolution.data });
|
|
87
|
+
if (Number(resolution.bytes || 0) !== data.byteLength || String(resolution.sha256 || '') !== sha256Hex(data)) return Object.freeze({ state: 'blocked', reason: 'required-workspace-package-byte-mismatch' });
|
|
88
|
+
return Object.freeze({
|
|
89
|
+
state: 'qualified',
|
|
90
|
+
kind: resolution.kind,
|
|
91
|
+
workspaceRelativePath: resolvedPath,
|
|
92
|
+
packagePath: String(resolution.packagePath || ''),
|
|
93
|
+
...(resolution.providerMode === 'archive' ? { workspaceId: String(workspace.id || ''), providerMode: 'archive', archivePackagePath: String(resolution.archivePackagePath || resolution.packagePath || ''), innerPath: String(resolution.innerPath || resolvedPath) } : {}),
|
|
94
|
+
bytes: data.byteLength,
|
|
95
|
+
sha256: sha256Hex(data)
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function resolveDescriptorMaterial(bundle, descriptor, byteProvider, target = '', requirementId = '', routeWorkspaceId = '', routePath = '') {
|
|
100
|
+
const expectedTarget = String(target || '');
|
|
101
|
+
const expectedRequirementId = String(requirementId || '');
|
|
102
|
+
const expectedRouteWorkspaceId = String(routeWorkspaceId || '');
|
|
103
|
+
const expectedRoutePath = normalizeWorkspacePath(routePath || '');
|
|
104
|
+
const matches = (descriptor.materialized || []).filter((entry) => {
|
|
105
|
+
if (expectedRequirementId && String(entry.requirementId || '') !== expectedRequirementId) return false;
|
|
106
|
+
if (expectedTarget && String(entry.referenceTarget || '') !== expectedTarget) return false;
|
|
107
|
+
if (expectedRouteWorkspaceId && entry.routeWorkspaceId && String(entry.routeWorkspaceId || '') !== expectedRouteWorkspaceId) return false;
|
|
108
|
+
if (expectedRoutePath && entry.routePath && normalizeWorkspacePath(entry.routePath || '') !== expectedRoutePath) return false;
|
|
109
|
+
return Boolean(expectedTarget || expectedRequirementId);
|
|
110
|
+
});
|
|
111
|
+
const byRepresentation = new Map();
|
|
112
|
+
for (const entry of matches) {
|
|
113
|
+
const key = entry.carrierKind === 'workspace-archive-entry'
|
|
114
|
+
? `${entry.workspaceId || ''}\u0000${entry.workspaceRelativePath || ''}\u0000${entry.sha256 || ''}\u0000${Number(entry.bytes || 0)}`
|
|
115
|
+
: `${entry.packagePath || ''}\u0000${entry.sha256 || ''}\u0000${Number(entry.bytes || 0)}`;
|
|
116
|
+
if (!byRepresentation.has(key)) byRepresentation.set(key, entry);
|
|
117
|
+
}
|
|
118
|
+
if (byRepresentation.size !== 1) return byRepresentation.size > 1 ? Object.freeze({ state: 'blocked', reason: 'required-material-carrier-ambiguous' }) : null;
|
|
119
|
+
const entry = [...byRepresentation.values()][0];
|
|
120
|
+
if (String(entry.carrierKind || '') === 'workspace-archive-entry') {
|
|
121
|
+
const resolved = resolveHandoffWorkspaceEntry(byteProvider, entry.workspaceId, entry.workspaceRelativePath);
|
|
122
|
+
if (resolved.state !== 'qualified') return Object.freeze({ state: 'blocked', reason: resolved.reason || 'required-material-workspace-provider-unqualified' });
|
|
123
|
+
const data = packageFileBytes({ data: resolved.data });
|
|
124
|
+
if (Number(entry.bytes || 0) !== data.byteLength || String(entry.sha256 || '') !== sha256Hex(data)) return Object.freeze({ state: 'blocked', reason: 'required-material-package-byte-mismatch' });
|
|
125
|
+
return Object.freeze({ state: 'qualified', kind: 'workspace-archive-entry', workspaceId: String(entry.workspaceId || ''), workspaceRelativePath: String(entry.workspaceRelativePath || ''), providerMode: 'archive', packagePath: String(resolved.packagePath || ''), archivePackagePath: String(resolved.archivePackagePath || resolved.packagePath || ''), innerPath: String(resolved.innerPath || entry.workspaceRelativePath || ''), bytes: data.byteLength, sha256: sha256Hex(data) });
|
|
126
|
+
}
|
|
127
|
+
const file = findFile(bundle, String(entry.packagePath || ''));
|
|
128
|
+
if (!file) return Object.freeze({ state: 'blocked', reason: 'required-material-package-byte-missing' });
|
|
129
|
+
const data = packageFileBytes(file);
|
|
130
|
+
if (Number(entry.bytes || 0) !== data.byteLength || String(entry.sha256 || '') !== sha256Hex(data)) return Object.freeze({ state: 'blocked', reason: 'required-material-package-byte-mismatch' });
|
|
131
|
+
return Object.freeze({ state: 'qualified', kind: 'materialized-required-material', packagePath: String(entry.packagePath || ''), bytes: data.byteLength, sha256: sha256Hex(data) });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function resolveRouteParent(bundle, descriptor, byteProvider, workspace, routePath, parent = {}, targetEntry = {}) {
|
|
135
|
+
const localTargets = [];
|
|
136
|
+
if (parent.trace && !isExternalReference(parent.trace)) localTargets.push(String(parent.trace));
|
|
137
|
+
for (const entry of parent.originEntries || []) {
|
|
138
|
+
if (String(entry?.label || '').trim() === 'relative' && entry?.target && !isExternalReference(entry.target)) localTargets.push(String(entry.target));
|
|
139
|
+
}
|
|
140
|
+
const candidates = new Map();
|
|
141
|
+
for (const target of localTargets) {
|
|
142
|
+
const resolvedPath = resolveWorkspaceReference(routePath, target);
|
|
143
|
+
if (!resolvedPath) continue;
|
|
144
|
+
const resolved = resolveHandoffWorkspaceEntry(byteProvider, workspace.id, resolvedPath);
|
|
145
|
+
if (resolved.state !== 'qualified') continue;
|
|
146
|
+
const data = packageFileBytes({ data: resolved.data });
|
|
147
|
+
if (Number(resolved.bytes || 0) !== data.byteLength || String(resolved.sha256 || '') !== sha256Hex(data)) continue;
|
|
148
|
+
const markdown = decodeUtf8(data);
|
|
149
|
+
if (!markdown) continue;
|
|
150
|
+
candidates.set(`${workspace.id}\u0000${resolvedPath}`, Object.freeze({ state: 'qualified', markdown, basis: 'parent-local-reference', workspaceRelativePath: resolvedPath, packagePath: String(resolved.packagePath || ''), sha256: sha256Hex(data) }));
|
|
151
|
+
}
|
|
152
|
+
if (candidates.size === 1) return [...candidates.values()][0];
|
|
153
|
+
if (candidates.size > 1) return Object.freeze({ state: 'ambiguous', reason: 'multiple-parent-local-reference-candidates' });
|
|
154
|
+
|
|
155
|
+
const digest = String(targetEntry?.value || '').trim();
|
|
156
|
+
if (!digest) return Object.freeze({ state: 'unavailable', reason: 'parent-target-digest-missing' });
|
|
157
|
+
const digestMatches = new Map();
|
|
158
|
+
for (const candidate of packageParentCandidates(bundle, descriptor, byteProvider)) {
|
|
159
|
+
const data = candidate.data || (candidate.packagePath ? packageFileBytes(findFile(bundle, candidate.packagePath) || {}) : new Uint8Array());
|
|
160
|
+
if (!data.byteLength) continue;
|
|
161
|
+
if (Number(candidate.bytes || data.byteLength) !== data.byteLength || (candidate.sha256 && String(candidate.sha256) !== sha256Hex(data))) continue;
|
|
162
|
+
const markdown = decodeUtf8(data);
|
|
163
|
+
if (!markdown) continue;
|
|
164
|
+
const self = validatedC14nV2PrimarySelfDigest(markdown);
|
|
165
|
+
if (self.state !== 'verified' || self.value !== digest) continue;
|
|
166
|
+
const key = `${candidate.workspaceId || ''}\u0000${candidate.workspaceRelativePath || ''}\u0000${candidate.packagePath || ''}`;
|
|
167
|
+
digestMatches.set(key, Object.freeze({ state: 'qualified', markdown, basis: 'parent-target-digest-candidate', workspaceRelativePath: normalizeWorkspacePath(candidate.workspaceRelativePath || ''), packagePath: String(candidate.packagePath || ''), sha256: sha256Hex(data) }));
|
|
168
|
+
}
|
|
169
|
+
if (digestMatches.size === 1) return [...digestMatches.values()][0];
|
|
170
|
+
if (digestMatches.size > 1) return Object.freeze({ state: 'ambiguous', reason: 'multiple-parent-target-digest-candidates' });
|
|
171
|
+
return Object.freeze({ state: 'unavailable', reason: 'parent-representation-not-carried' });
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function packageParentCandidates(bundle = {}, descriptor = {}, byteProvider = {}) {
|
|
175
|
+
const candidates = new Map();
|
|
176
|
+
for (const workspace of descriptor.workspaceMaterializations || []) {
|
|
177
|
+
for (const entry of listHandoffWorkspaceEntries(byteProvider, workspace.id)) {
|
|
178
|
+
if (!/\.trace\.md$/i.test(String(entry.path || ''))) continue;
|
|
179
|
+
const key = `${workspace.id}\u0000${entry.path}`;
|
|
180
|
+
if (!candidates.has(key)) candidates.set(key, Object.freeze({ workspaceId: String(workspace.id || ''), packagePath: String(entry.packagePath || entry.archivePackagePath || ''), workspaceRelativePath: normalizeWorkspacePath(entry.path), bytes: Number(entry.bytes || 0), sha256: String(entry.sha256 || ''), data: entry.data }));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
for (const entry of descriptor.materialized || []) {
|
|
184
|
+
if (String(entry.carrierKind || '') === 'workspace-archive-entry') continue;
|
|
185
|
+
const packagePath = String(entry.packagePath || '');
|
|
186
|
+
if (!packagePath || candidates.has(`package\u0000${packagePath}`)) continue;
|
|
187
|
+
const file = findFile(bundle, packagePath);
|
|
188
|
+
candidates.set(`package\u0000${packagePath}`, Object.freeze({ packagePath, workspaceRelativePath: normalizeWorkspacePath(entry.originalPath || ''), bytes: Number(entry.bytes || 0), sha256: String(entry.sha256 || ''), data: file ? packageFileBytes(file) : new Uint8Array() }));
|
|
189
|
+
}
|
|
190
|
+
return [...candidates.values()];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function resolveWorkspaceReference(routePath, target) {
|
|
194
|
+
const raw = safeDecodeURIComponent(String(target || '').split('#')[0].split('?')[0]);
|
|
195
|
+
if (!raw || raw.startsWith('/') || raw.startsWith('\\')) return '';
|
|
196
|
+
const base = normalizeWorkspacePath(routePath).split('/').slice(0, -1);
|
|
197
|
+
for (const part of raw.replace(/\\/g, '/').split('/')) {
|
|
198
|
+
if (!part || part === '.') continue;
|
|
199
|
+
if (part === '..') { if (!base.length) return ''; base.pop(); }
|
|
200
|
+
else base.push(part);
|
|
201
|
+
}
|
|
202
|
+
return normalizeWorkspacePath(base.join('/'));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function isExternalReference(value = '') { return /^[a-z][a-z0-9+.-]*:/i.test(String(value || '')) || String(value || '').startsWith('//'); }
|
|
206
|
+
function safeDecodeURIComponent(value = '') { try { return decodeURIComponent(value); } catch { return ''; } }
|
|
207
|
+
|
|
208
|
+
function parseHandoffParties(markdown = '') {
|
|
209
|
+
const text = String(markdown || '');
|
|
210
|
+
const heading = /^##\s+Handoff Parties\s*$/mi.exec(text);
|
|
211
|
+
if (!heading) return Object.freeze({ from: '', to: '' });
|
|
212
|
+
const rest = text.slice(heading.index + heading[0].length);
|
|
213
|
+
const nextHeading = /^##\s+/m.exec(rest);
|
|
214
|
+
const section = nextHeading ? rest.slice(0, nextHeading.index) : rest;
|
|
215
|
+
return Object.freeze({ from: field(section, 'From'), to: field(section, 'To') });
|
|
216
|
+
}
|
|
217
|
+
function field(section, name) {
|
|
218
|
+
const match = String(section || '').match(new RegExp(`^\\s*-\\s+${name}:\\s*(.+?)\\s*$`, 'mi'));
|
|
219
|
+
return String(match?.[1] || '').trim();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function carrierFilename(workspaceSlug, dimension, from, to) {
|
|
223
|
+
return `${[slug(workspaceSlug), slug(dimension), slug(from), 'to', slug(to)].filter(Boolean).join('-')}.handoff-package.zip`;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function slug(value = '') { return String(value || '').trim().toLowerCase().normalize('NFKD').replace(/[\u0300-\u036f]/g, '').replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 120); }
|
|
227
|
+
|
|
228
|
+
function isWorkspaceRelativeArtifactPath(path = '') { return Boolean(path) && !path.startsWith('/') && !path.startsWith('handoff.workspaces/') && !path.startsWith('tiinex.package/') && !path.startsWith('../') && !path.includes('/../') && /\.trace\.md$/i.test(path); }
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { packageFileBytes } from '../../../export/package.bytes.js';
|
|
2
|
+
|
|
3
|
+
export function normalizeWorkspacePath(value = '') { return String(value || '').trim().replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\/+/, ''); }
|
|
4
|
+
export function findFile(bundle = {}, path = '') { return (bundle.files || []).find((file) => String(file.path || '') === String(path || '')) || null; }
|
|
5
|
+
export function parseJsonFile(file = null) { try { return file ? JSON.parse(decodeUtf8(packageFileBytes(file))) : null; } catch { return null; } }
|
|
6
|
+
export function decodeUtf8(data) { try { return new TextDecoder('utf-8', { fatal: true }).decode(data); } catch { return ''; } }
|
|
7
|
+
export function deepFreeze(value) { if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value; if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return value; for (const child of Object.values(value)) deepFreeze(child); return Object.freeze(value); }
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { packageFileBytes } from '../../../export/package.bytes.js';
|
|
2
|
+
import { handoffWorkspaceProviderForId } from './workspaceByteProvider.js';
|
|
3
|
+
|
|
4
|
+
export function qualifyHandoffCarrierWorkspaces(bundle = {}, descriptor = {}, byteProvider = null) {
|
|
5
|
+
const manifest = bundle.manifest || parseJsonFile(findFile(bundle, 'tiinex.package/manifest.json')) || {};
|
|
6
|
+
const primaryId = String(manifest.packageScope?.workspaceId || manifest.workspaceId || '');
|
|
7
|
+
const primaryTitle = String(manifest.packageScope?.workspaceTitle || manifest.title || primaryId || '');
|
|
8
|
+
const raw = descriptor.workspaceMaterializations || [];
|
|
9
|
+
const counts = new Map();
|
|
10
|
+
for (const workspace of raw) {
|
|
11
|
+
const id = String(workspace.id || '');
|
|
12
|
+
if (id) counts.set(id, (counts.get(id) || 0) + 1);
|
|
13
|
+
}
|
|
14
|
+
return Object.freeze(raw.map((workspace) => {
|
|
15
|
+
const id = String(workspace.id || '');
|
|
16
|
+
const title = String(id === primaryId ? (primaryTitle || workspace.title || id) : (workspace.title || workspace.name || workspace.source?.workspaceTitle || workspace.source?.title || id || 'workspace'));
|
|
17
|
+
const reasons = [];
|
|
18
|
+
if (!id) reasons.push('workspace-id-unresolved');
|
|
19
|
+
if (id && counts.get(id) !== 1) reasons.push('workspace-id-ambiguous');
|
|
20
|
+
if (String(workspace.qualification || '') !== 'qualified') reasons.push('workspace-qualification-unqualified');
|
|
21
|
+
if (String(workspace.correlationStatus || '') !== 'qualified') reasons.push('workspace-correlation-unqualified');
|
|
22
|
+
const providerWorkspace = byteProvider ? handoffWorkspaceProviderForId(byteProvider, id) : null;
|
|
23
|
+
if (byteProvider && providerWorkspace?.state !== 'qualified') reasons.push(...(providerWorkspace?.reasons || [`workspace-provider-${providerWorkspace?.state || 'unresolved'}`]));
|
|
24
|
+
const state = reasons.length ? (reasons.includes('workspace-id-ambiguous') || providerWorkspace?.state === 'ambiguous' ? 'ambiguous' : 'blocked') : 'qualified';
|
|
25
|
+
return deepFreeze({ state, id, title, slug: slug(title || id), materialization: workspace, provider: providerWorkspace, reasons: Object.freeze([...new Set(reasons)]) });
|
|
26
|
+
}).sort((a, b) => a.id.localeCompare(b.id)));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function selectHandoffCarrierDefaultWorkspace(bundle = {}, workspaces = []) {
|
|
30
|
+
const manifest = bundle.manifest || parseJsonFile(findFile(bundle, 'tiinex.package/manifest.json')) || {};
|
|
31
|
+
const primaryId = String(manifest.packageScope?.workspaceId || manifest.workspaceId || '');
|
|
32
|
+
const matches = workspaces.filter((workspace) => workspace.id === primaryId);
|
|
33
|
+
if (matches.length === 1) return matches[0];
|
|
34
|
+
return workspaces.length === 1 ? workspaces[0] : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function handoffCarrierWorkspaceForRoute(workspaces = [], workspaceId = '') {
|
|
38
|
+
const matches = workspaces.filter((workspace) => workspace.id === String(workspaceId || ''));
|
|
39
|
+
if (matches.length === 1) return matches[0];
|
|
40
|
+
return deepFreeze({ state: matches.length > 1 ? 'ambiguous' : 'unresolved', id: String(workspaceId || ''), title: String(workspaceId || ''), slug: slug(workspaceId), materialization: null, provider: null, reasons: Object.freeze([matches.length > 1 ? 'workspace-id-ambiguous' : 'workspace-id-unresolved']) });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function projectHandoffCarrierWorkspace(workspace = {}) {
|
|
44
|
+
return Object.freeze({ id: String(workspace.id || ''), title: String(workspace.title || workspace.id || ''), slug: String(workspace.slug || slug(workspace.title || workspace.id || '')), qualification: String(workspace.state || 'unresolved') });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function findProjectedHandoffCarrierWorkspace(projection = {}, workspaceId = '') {
|
|
48
|
+
return (projection.workspaces || []).find((workspace) => String(workspace.id || '') === String(workspaceId || '')) || null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function findFile(bundle = {}, path = '') { return (bundle.files || []).find((file) => String(file.path || '') === String(path || '')) || null; }
|
|
52
|
+
function parseJsonFile(file = null) { try { return file ? JSON.parse(new TextDecoder().decode(packageFileBytes(file))) : null; } catch { return null; } }
|
|
53
|
+
function slug(value = '') { return String(value || '').trim().toLowerCase().normalize('NFKD').replace(/[\u0300-\u036f]/g, '').replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 120); }
|
|
54
|
+
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); }
|