@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,218 @@
|
|
|
1
|
+
import { packageFileByteView, packageFileBytes, sha256Hex, utf8Bytes } from '../../../export/package.bytes.js';
|
|
2
|
+
import { validatedC14nV2PrimarySelfDigest } from '../../../integrity/integrity.c14nV2.js';
|
|
3
|
+
import { inspectStoredWorkspaceArchive, HANDOFF_WORKSPACE_BYTE_PROVIDER_SCHEMA_ID, HANDOFF_WORKSPACE_ARCHIVE_BINDING_SCHEMA_ID, HANDOFF_WORKSPACE_ARCHIVE_CODEC, HANDOFF_WORKSPACE_ARCHIVE_PROVIDER_KIND, HANDOFF_WORKSPACE_INNER_PATH_NORMALIZATION } from './workspaceByteProvider.js';
|
|
4
|
+
import { boundedRecipientToken } from './recipientV2.inspect.pathToken.js';
|
|
5
|
+
|
|
6
|
+
export function indexRecipientFiles(files = [], findings = []) {
|
|
7
|
+
const map = new Map();
|
|
8
|
+
for (const file of files) {
|
|
9
|
+
const path = String(file.path || '');
|
|
10
|
+
const list = map.get(path) || [];
|
|
11
|
+
list.push(file);
|
|
12
|
+
map.set(path, list);
|
|
13
|
+
}
|
|
14
|
+
for (const [path, list] of map) if (list.length !== 1) findings.push(finding('error', 'portable.handoff-v2-surface.path-duplicate', 'Recipient-facing v2 root contains a duplicate path.', { path, count: list.length }));
|
|
15
|
+
return map;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function oneRecipientFile(index, path = '') {
|
|
19
|
+
const list = index.get(String(path || '')) || [];
|
|
20
|
+
return list.length === 1 ? list[0] : null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function inspectRecipientZipPayload(file, facts = {}, findings = [], role = 'payload', verifiedIdentity = null) {
|
|
24
|
+
if (!file) return null;
|
|
25
|
+
const data = packageFileByteView(file);
|
|
26
|
+
const expectedPath = String(facts.archivePath || '');
|
|
27
|
+
if (expectedPath && expectedPath !== String(file.path || '')) findings.push(finding('error', `portable.handoff-v2-surface.${role}.path-mismatch`, 'Payload artifact local archive path does not resolve to the inspected payload.', { expectedPath, actualPath: file.path || '' }));
|
|
28
|
+
if (Number(facts.archiveBytes || 0) !== data.byteLength) findings.push(finding('error', `portable.handoff-v2-surface.${role}.bytes-mismatch`, 'Payload byte length differs from its qualified visible declaration.', { path: file.path || '' }));
|
|
29
|
+
const archiveSha256 = reusableVerifiedIdentity(verifiedIdentity, data) || sha256Hex(data);
|
|
30
|
+
if (String(facts.archiveSha256 || '') !== archiveSha256) findings.push(finding('error', `portable.handoff-v2-surface.${role}.sha256-mismatch`, 'Payload digest differs from its qualified visible declaration.', { path: file.path || '' }));
|
|
31
|
+
const archive = inspectStoredWorkspaceArchive(data, { ownedBytes: true });
|
|
32
|
+
if (archive.state !== 'qualified') for (const item of archive.findings || []) findings.push(finding('error', `portable.handoff-v2-surface.${role}.archive-invalid`, item.message || 'Stored ZIP payload is invalid.', { path: file.path || '', cause: item.code || '' }));
|
|
33
|
+
return Object.freeze({ data, sha256: archiveSha256, bytes: data.byteLength, archive });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
function reusableVerifiedIdentity(identity, data) {
|
|
39
|
+
if (!identity || Number(identity.bytes) !== data.byteLength) return '';
|
|
40
|
+
const digest = String(identity.sha256 || '').toLowerCase();
|
|
41
|
+
return /^[a-f0-9]{64}$/.test(digest) ? digest : '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function buildQualifiedRecipientV2WorkspaceByteProvider(workspaceParts = []) {
|
|
45
|
+
const providerFindings = [];
|
|
46
|
+
const idCounts = new Map();
|
|
47
|
+
for (const part of workspaceParts) idCounts.set(String(part?.workspaceId || ''), (idCounts.get(String(part?.workspaceId || '')) || 0) + 1);
|
|
48
|
+
const workspaces = workspaceParts.map((part) => {
|
|
49
|
+
const descriptorPart = part?.descriptorPart || {};
|
|
50
|
+
const workspace = descriptorPart.workspace || {};
|
|
51
|
+
const binding = descriptorPart.binding || {};
|
|
52
|
+
const archive = part?.archive || {};
|
|
53
|
+
const representation = part?.representation || {};
|
|
54
|
+
const payload = part?.payload || {};
|
|
55
|
+
const parsedEntries = archive.archive?.entries || [];
|
|
56
|
+
const workspaceId = String(workspace.id || part?.workspaceId || '');
|
|
57
|
+
const reasons = [];
|
|
58
|
+
const reject = (code, detail = '') => reasons.push(Object.freeze({ code, detail }));
|
|
59
|
+
if (!workspaceId || idCounts.get(workspaceId) !== 1) reject('workspace-identity-ambiguous', `count=${idCounts.get(workspaceId) || 0}`);
|
|
60
|
+
if (part?.artifact?.schemaId !== 'tiinex.workspace.v1' || part?.artifact?.status !== 'qualified') reject('workspace-artifact-unqualified');
|
|
61
|
+
if (part?.representationArtifact?.schemaId !== 'tiinex.workspace.representation.v1' || part?.representationArtifact?.status !== 'qualified') reject('workspace-representation-unqualified');
|
|
62
|
+
if (part?.payloadArtifact?.schemaId !== 'tiinex.external.payload.v1' || part?.payloadArtifact?.status !== 'qualified') reject('workspace-representation-payload-unqualified');
|
|
63
|
+
if (representation.workspaceArtifactPath !== part?.artifact?.path) reject('workspace-representation-workspace-endpoint-mismatch');
|
|
64
|
+
if (representation.payloadArtifactPath !== part?.payloadArtifact?.path) reject('workspace-representation-payload-endpoint-mismatch');
|
|
65
|
+
const coverage = representation.coverage === 'bounded' ? 'bounded' : representation.coverage === 'complete' ? 'complete' : '';
|
|
66
|
+
const expectedRepresentationKind = coverage === 'bounded' ? 'exact-bounded-workspace-byte-tree-archive' : 'exact-workspace-byte-tree-archive';
|
|
67
|
+
const expectedActivationRule = coverage === 'bounded' ? 'verified-bounded-only' : 'verified-complete-only';
|
|
68
|
+
const expectedSelectionRule = coverage === 'bounded' ? 'explicit-binding-per-bounded-scope' : 'exactly-one-binding-per-workspace';
|
|
69
|
+
if (!coverage || representation.representationKind !== expectedRepresentationKind || representation.bindingState !== 'verified') reject(coverage === 'bounded' ? 'workspace-representation-not-verified-bounded' : 'workspace-representation-not-verified-complete');
|
|
70
|
+
if (coverage === 'bounded' && (representation.scopeBasis !== 'exact-representation-entry-set' || representation.includedEntryAuthority !== 'qualified-decoded-entry-set' || representation.omittedEntryMeaning !== 'outside-representation-not-absent-from-workspace' || representation.sourceMembershipClaim !== 'represented-entries-are-workspace-relative-source-bytes' || representation.recoveryClosureBoundary !== 'separate-qualified-closure')) reject('workspace-representation-bounded-scope-invalid');
|
|
71
|
+
if (representation.workspaceTreeRoot !== '.' || representation.archiveEntryRoot !== '.' || representation.pathMapping !== 'identity-relative-paths' || representation.collisionPolicy !== 'reject-ambiguous-or-unsafe-paths' || representation.decoderRequirement !== 'deterministic stored ZIP with safe-entry validation') reject('workspace-representation-correlation-invalid');
|
|
72
|
+
if (representation.activationRule !== expectedActivationRule || representation.payloadIntegrityRequirement !== 'verified-exact-payload-bytes' || representation.coverageRequirement !== coverage || representation.stalenessRule !== 'requalify-on-binding-relevant-change' || representation.selectionRule !== expectedSelectionRule || representation.multiWorkspaceIsolation !== 'independent-binding-closure') reject('workspace-representation-provider-contract-invalid');
|
|
73
|
+
if (representation.pathMapping === 'manifest' && !representation.mappingManifest) reject('workspace-representation-mapping-manifest-missing');
|
|
74
|
+
if (payload.mediaType !== 'application/zip' || payload.format !== 'deterministic stored ZIP' || payload.integrityStatus !== 'verified' || payload.integrityMethod !== 'sha256' || payload.integrityTarget !== 'exact payload bytes as carried at the declared local Location') reject('workspace-representation-payload-contract-invalid');
|
|
75
|
+
if (payload.location !== String(part?.archiveFile?.path || '')) reject('workspace-representation-payload-location-mismatch');
|
|
76
|
+
if (Number(payload.bytes || 0) !== Number(archive.bytes || 0) || String(payload.integrityValue || '') !== String(archive.sha256 || '')) reject('workspace-representation-payload-integrity-mismatch');
|
|
77
|
+
if (archive.archive?.state !== 'qualified') reject('workspace-representation-payload-decoder-unqualified');
|
|
78
|
+
if (String(representation.workspaceArtifactInnerPath || '') !== String(part?.sourceTargetEntry?.path || '')) reject('workspace-representation-inner-workspace-mismatch');
|
|
79
|
+
if (part?.targetQualification?.state !== 'qualified') reject('workspace-representation-inner-workspace-unqualified');
|
|
80
|
+
const exactEntriesFingerprint = recipientEntriesFingerprint(parsedEntries);
|
|
81
|
+
const facts = part?.facts || {};
|
|
82
|
+
const representationFacts = part?.representationArtifact?.facts || {};
|
|
83
|
+
const payloadFacts = part?.payloadArtifact?.facts || {};
|
|
84
|
+
if (String(facts.sourceWorkspaceTargetInnerPath || '') !== String(representation.workspaceArtifactInnerPath || '') || String(facts.sourceWorkspaceTargetSha256 || '') !== String(part?.targetFile?.sha256 || '') || Number(facts.sourceWorkspaceTargetBytes || 0) !== Number(part?.targetFile?.bytes || 0) || Number(facts.entryCount || 0) !== parsedEntries.length || String(facts.entriesFingerprint || '') !== exactEntriesFingerprint || String(facts.coverage || 'complete') !== coverage || String(facts.coverageState || facts.completenessState || '') !== 'qualified') reject('workspace-transport-witness-stale');
|
|
85
|
+
if (String(representationFacts.workspaceId || '') !== workspaceId || String(representationFacts.workspaceArtifactPath || '') !== String(part?.artifact?.path || '') || String(representationFacts.payloadArtifactPath || '') !== String(part?.payloadArtifact?.path || '') || String(representationFacts.sourceWorkspaceTargetInnerPath || '') !== String(representation.workspaceArtifactInnerPath || '') || String(representationFacts.archivePath || '') !== String(payload.location || '') || String(representationFacts.archiveSha256 || '') !== String(archive.sha256 || '') || Number(representationFacts.entryCount || 0) !== parsedEntries.length || String(representationFacts.entriesFingerprint || '') !== exactEntriesFingerprint || String(representationFacts.coverage || 'complete') !== coverage || String(representationFacts.coverageState || representationFacts.completenessState || '') !== 'qualified') reject('workspace-representation-transport-witness-stale');
|
|
86
|
+
if (String(payloadFacts.workspaceId || '') !== workspaceId || String(payloadFacts.archivePath || '') !== String(payload.location || '') || String(payloadFacts.archiveSha256 || '') !== String(archive.sha256 || '')) reject('workspace-representation-payload-transport-witness-stale');
|
|
87
|
+
const declaredByPath = new Map((binding.entryMap?.entries || []).map((entry) => [String(entry.path || ''), entry]));
|
|
88
|
+
const archivePath = String(binding.representation?.packagePath || part?.archiveFile?.path || '');
|
|
89
|
+
const entries = parsedEntries.map((entry) => {
|
|
90
|
+
const declared = declaredByPath.get(String(entry.path || '')) || {};
|
|
91
|
+
return deepFreeze({ path: String(entry.path || ''), innerPath: String(entry.path || ''), archivePackagePath: archivePath, packagePath: archivePath, bytes: Number(entry.bytes || 0), sha256: String(entry.sha256 || ''), referenceTarget: String(declared.referenceTarget || ''), data: entry.data });
|
|
92
|
+
});
|
|
93
|
+
const state = reasons.length ? 'blocked' : 'qualified';
|
|
94
|
+
for (const reason of reasons) providerFindings.push(finding('error', `portable.handoff-v2-surface.workspace-provider.${reason.code}`, 'Canonical Workspace Representation provider activation failed closed.', { workspaceId, detail: reason.detail || '' }));
|
|
95
|
+
return deepFreeze({
|
|
96
|
+
state,
|
|
97
|
+
id: workspaceId,
|
|
98
|
+
title: String(workspace.title || workspace.id || part?.workspaceId || ''),
|
|
99
|
+
mode: 'archive',
|
|
100
|
+
materialization: workspace,
|
|
101
|
+
entries: Object.freeze(entries),
|
|
102
|
+
workspaceTarget: deepFreeze({ ...(binding.workspaceTarget || {}), data: packageFileByteView(part?.targetFile || {}) }),
|
|
103
|
+
archive: deepFreeze({ ...(binding.representation || {}), data: archive.data || new Uint8Array() }),
|
|
104
|
+
binding,
|
|
105
|
+
reasons: Object.freeze(reasons),
|
|
106
|
+
authority: Object.freeze({ locatorAuthority: false, filenameAuthority: false, packagePlacementAuthority: false, bindingAuthority: 'schema-valid-tiinex.workspace.representation.v1-visible-binding-plus-schema-valid-external-payload-plus-exact-qualified-archive-bytes', hiddenTransportBindingAuthority: false })
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
return deepFreeze({
|
|
110
|
+
schema: HANDOFF_WORKSPACE_BYTE_PROVIDER_SCHEMA_ID,
|
|
111
|
+
status: workspaces.length > 0 && workspaces.every((workspace) => workspace.state === 'qualified') ? 'ready' : 'blocked',
|
|
112
|
+
workspaces: Object.freeze(workspaces),
|
|
113
|
+
findings: Object.freeze(providerFindings),
|
|
114
|
+
boundary: 'Recipient-v2 archive provider activation is authorized only by one schema-valid verified complete-or-bounded tiinex.workspace.representation.v1 artifact, its explicitly referenced schema-valid External Payload, and exact qualified payload bytes. Bounded scope never implies whole-Workspace completeness; hidden transport binding metadata has no semantic provider authority.'
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function recipientEntryIdentities(entries = []) {
|
|
119
|
+
return entries.map((entry) => ({ path: String(entry.path || ''), bytes: Number(entry.bytes || 0), sha256: String(entry.sha256 || '') })).sort((a, b) => a.path.localeCompare(b.path));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function recipientEntriesFingerprint(entries = []) {
|
|
123
|
+
return sha256Hex(utf8Bytes(stableJson(recipientEntryIdentities(entries))));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function recipientWorkspaceDescriptor(input = {}) {
|
|
127
|
+
const facts = input.facts || {};
|
|
128
|
+
const representation = input.representation || {};
|
|
129
|
+
const payload = input.payload || {};
|
|
130
|
+
const entries = recipientEntryIdentities(input.entries || []).map((entry) => Object.freeze({ ...entry, referenceTarget: '' }));
|
|
131
|
+
const workspaceId = String(input.workspaceId || facts.workspaceId || '');
|
|
132
|
+
const targetPath = String(input.targetPackagePath || '');
|
|
133
|
+
const targetInnerPath = String(representation.workspaceArtifactInnerPath || '');
|
|
134
|
+
const archivePath = String(payload.location || input.archiveFile?.path || '');
|
|
135
|
+
const targetFile = input.targetFile || {};
|
|
136
|
+
const selfIntegrity = validatedC14nV2PrimarySelfDigest(input.targetMarkdown || '');
|
|
137
|
+
const archiveFile = input.archiveFile || {};
|
|
138
|
+
const totalBytes = entries.reduce((sum, entry) => sum + entry.bytes, 0);
|
|
139
|
+
const coverage = representation.coverage === 'bounded' ? 'bounded' : 'complete';
|
|
140
|
+
const coverageEvidence = Object.freeze({ state: 'qualified', basis: coverage === 'bounded' ? 'canonical-verified-bounded-workspace-representation-plus-exact-external-payload-and-qualified-bounded-entry-set' : 'canonical-verified-complete-workspace-representation-plus-exact-external-payload-and-qualified-complete-entry-set', entryCount: entries.length, totalBytes, ...(coverage === 'bounded' ? { scopeBasis: representation.scopeBasis, includedEntryAuthority: representation.includedEntryAuthority, omittedEntryMeaning: representation.omittedEntryMeaning, sourceMembershipClaim: representation.sourceMembershipClaim, recoveryClosureBoundary: representation.recoveryClosureBoundary } : {}) });
|
|
141
|
+
const transportCorrelationKey = recipientLocalWorkspaceCorrelationKey({ workspaceId, representation, payload, targetFile, entries });
|
|
142
|
+
const workspace = Object.freeze({
|
|
143
|
+
id: workspaceId,
|
|
144
|
+
title: workspaceId,
|
|
145
|
+
materialization: coverage,
|
|
146
|
+
qualification: 'qualified',
|
|
147
|
+
correlationStatus: 'qualified',
|
|
148
|
+
transportCorrelationKey,
|
|
149
|
+
completenessEvidence: coverage === 'complete' ? coverageEvidence : Object.freeze({}),
|
|
150
|
+
scopeEvidence: coverage === 'bounded' ? coverageEvidence : Object.freeze({}),
|
|
151
|
+
includedEntries: Object.freeze(entries)
|
|
152
|
+
});
|
|
153
|
+
const binding = Object.freeze({
|
|
154
|
+
schema: HANDOFF_WORKSPACE_ARCHIVE_BINDING_SCHEMA_ID,
|
|
155
|
+
version: 1,
|
|
156
|
+
workspaceId,
|
|
157
|
+
transportCorrelationKey,
|
|
158
|
+
workspaceTarget: Object.freeze({ packagePath: targetPath, innerPath: targetInnerPath, bytes: Number(targetFile.bytes || 0), sha256: String(targetFile.sha256 || ''), schema: 'tiinex.workspace.v1', selfIntegrity: Object.freeze({ state: String(selfIntegrity.state || ''), value: String(selfIntegrity.value || '') }), locatorAuthority: false }),
|
|
159
|
+
coverage,
|
|
160
|
+
representation: Object.freeze({ kind: coverage === 'bounded' ? 'bounded-workspace-snapshot' : 'complete-workspace-snapshot', packagePath: archivePath, mediaType: 'application/zip', codec: HANDOFF_WORKSPACE_ARCHIVE_CODEC, bytes: Number(archiveFile.bytes || 0), digest: Object.freeze({ method: 'sha256', value: String(archiveFile.sha256 || ''), target: 'archive-bytes-as-carried' }), deterministic: true, locatorAuthority: false }),
|
|
161
|
+
entryMap: Object.freeze({ normalization: HANDOFF_WORKSPACE_INNER_PATH_NORMALIZATION, count: entries.length, entries: Object.freeze(entries) }),
|
|
162
|
+
completeness: coverage === 'complete' ? Object.freeze({ ...coverageEvidence, entriesFingerprint: '' }) : Object.freeze({}),
|
|
163
|
+
scope: coverage === 'bounded' ? Object.freeze({ ...coverageEvidence, entriesFingerprint: '' }) : Object.freeze({}),
|
|
164
|
+
selection: Object.freeze({ rule: coverage === 'bounded' ? 'explicit-binding-per-bounded-scope' : 'exactly-one-binding-per-workspace', representationArtifactAuthority: 'explicit-recipient-workspace-representation-link' }),
|
|
165
|
+
provider: Object.freeze({ kind: String(facts.providerKind || HANDOFF_WORKSPACE_ARCHIVE_PROVIDER_KIND), state: 'ready', addressing: 'qualified-workspace-id-plus-normalized-inner-path', fallback: 'none', materialization: coverage }),
|
|
166
|
+
authority: Object.freeze({ workspaceIdentity: 'explicit-canonical-workspace-representation-workspace-endpoint-plus-exact-workspace-target-byte-identity', archiveIdentity: 'explicit-external-payload-endpoint-plus-exact-archive-byte-digest', canonicalRepresentationSchema: 'tiinex.workspace.representation.v1', hiddenTransportBindingAuthority: false, pathAuthority: false, adjacencyAuthority: false, orderingAuthority: false })
|
|
167
|
+
});
|
|
168
|
+
return Object.freeze({ workspace, binding });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
function recipientLocalWorkspaceCorrelationKey(input = {}) {
|
|
173
|
+
const identity = {
|
|
174
|
+
format: 'recipient-v2-canonical-workspace-representation-binding',
|
|
175
|
+
workspaceId: String(input.workspaceId || ''),
|
|
176
|
+
workspaceArtifactPath: String(input.representation?.workspaceArtifactPath || ''),
|
|
177
|
+
payloadArtifactPath: String(input.representation?.payloadArtifactPath || ''),
|
|
178
|
+
sourceWorkspaceTargetInnerPath: String(input.representation?.workspaceArtifactInnerPath || ''),
|
|
179
|
+
sourceWorkspaceTargetSha256: String(input.targetFile?.sha256 || ''),
|
|
180
|
+
sourceWorkspaceTargetBytes: Number(input.targetFile?.bytes || 0),
|
|
181
|
+
archivePath: String(input.payload?.location || ''),
|
|
182
|
+
archiveSha256: String(input.payload?.integrityValue || ''),
|
|
183
|
+
entriesFingerprint: recipientEntriesFingerprint(input.entries || []),
|
|
184
|
+
coverage: String(input.representation?.coverage || 'complete')
|
|
185
|
+
};
|
|
186
|
+
return `recipient-v2:${sha256Hex(utf8Bytes(stableJson(identity)))}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function virtualCacheMaterial(cache = {}, findings = []) {
|
|
190
|
+
const archive = cache.archive?.archive;
|
|
191
|
+
const byPath = new Map((archive?.entries || []).map((entry) => [String(entry.path || ''), entry]));
|
|
192
|
+
const files = [];
|
|
193
|
+
const materialized = [];
|
|
194
|
+
for (const item of cache.facts?.materials || []) {
|
|
195
|
+
const entry = byPath.get(String(item.archiveEntry || ''));
|
|
196
|
+
if (!entry) {
|
|
197
|
+
findings.push(finding('error', 'portable.handoff-v2-surface.cache.entry-missing', 'Context cache declaration does not resolve to exactly one archive entry.', { requirementId: item.requirementId || '', archiveEntry: item.archiveEntry || '' }));
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (Number(item.bytes || 0) !== Number(entry.bytes || 0) || String(item.sha256 || '') !== String(entry.sha256 || '')) findings.push(finding('error', 'portable.handoff-v2-surface.cache.entry-identity-mismatch', 'Context cache entry bytes differ from its visible declaration.', { requirementId: item.requirementId || '', archiveEntry: item.archiveEntry || '' }));
|
|
201
|
+
const packagePath = `recipient.v2.cache/${boundedRecipientToken(cache.facts?.workspaceId || 'workspace')}/${boundedRecipientToken(item.requirementId || item.archiveEntry)}.bin`;
|
|
202
|
+
files.push(Object.freeze({ path: packagePath, data: entry.data, size: entry.bytes, kind: 'recipient-v2-virtual-cache-material' }));
|
|
203
|
+
materialized.push(Object.freeze({ requirementId: String(item.requirementId || ''), classification: String(item.classification || ''), referenceTarget: String(item.referenceTarget || ''), originalPath: String(item.originalPath || ''), packagePath, carrierKind: 'detached-material', bytes: Number(entry.bytes || 0), sha256: String(entry.sha256 || ''), authority: Object.freeze({ carrierDedupBasis: 'visible-cache-artifact-plus-exact-archive-entry-byte-identity' }) }));
|
|
204
|
+
}
|
|
205
|
+
return Object.freeze({ files: Object.freeze(files), materialized: Object.freeze(materialized) });
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
export function isForbiddenLegacyV2Path(path = '') {
|
|
210
|
+
const value = String(path || '');
|
|
211
|
+
return value.startsWith('context/') || value.startsWith('handoff.workspaces/') || value.startsWith('tiinex.bootstrap/') || value.startsWith('tiinex.package/') || /^handoff-entrypoint-.*\.trace\.md$/i.test(value);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function finding(severity, code, message, extra = {}) { return Object.freeze({ severity, code, message, ...extra }); }
|
|
215
|
+
export function stableJson(value) { return JSON.stringify(sortJson(value)); }
|
|
216
|
+
export function dedupeFindings(items = []) { const map = new Map(); for (const item of items) { const key = `${item.severity || ''}:${item.code || ''}:${item.path || item.workspaceId || item.requirementId || ''}:${item.message || ''}`; if (!map.has(key)) map.set(key, item); } return [...map.values()]; }
|
|
217
|
+
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); }
|
|
218
|
+
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])])); }
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { packageFileBytes, sha256Hex } from '../../../export/package.bytes.js';
|
|
2
|
+
import { exportFileMapZipUint8Array } from '../../../export/package.zip.js';
|
|
3
|
+
import { inspectStoredWorkspaceArchive } from './workspaceByteProvider.js';
|
|
4
|
+
import { buildHandoffCarrierProjection } from './carrierProjection.js';
|
|
5
|
+
import { handoffWorkspaceProviderForId } from './workspaceByteProvider.js';
|
|
6
|
+
import { inspectRecipientV2Artifact } from './recipientV2.artifacts.js';
|
|
7
|
+
import { RECIPIENT_V2_FORMAT_ID, RECIPIENT_V2_READ_PATH } from './recipientV2.topology.js';
|
|
8
|
+
import { recipientColdProjection } from './recipientV2.coldProjection.js';
|
|
9
|
+
import { RECIPIENT_V2_ROUTE_SELECTION_AUTHORITY, RECIPIENT_V2_SIBLING_ROUTE_INFERENCE } from './recipientV2.entryContract.js';
|
|
10
|
+
import { buildQualifiedRecipientV2WorkspaceByteProvider, dedupeFindings, deepFreeze, finding, indexRecipientFiles, isForbiddenLegacyV2Path } from './recipientV2.inspect.helpers.js';
|
|
11
|
+
import { buildPackageLocalParentResolver, inspectRoutePointers, parentTrace } from './recipientV2.lineage.js';
|
|
12
|
+
import { inspectRecipientV2TransportManifest, recipientV2FactsForFile, RECIPIENT_V2_TRANSPORT_MANIFEST_PATH } from './recipientV2.transportManifest.js';
|
|
13
|
+
import { inspectRecipientFacingV2ArtifactFirstPhase1, isRecipientV2ArtifactFirstPhase1Surface } from './recipientV2.artifactFirstPhase1.js';
|
|
14
|
+
import { inspectRecipientFacingV2PackageV1, isRecipientV2PackageV1Surface } from './recipientV2.packageV1.js';
|
|
15
|
+
import { projectRecipientV2EndpointRoles, projectRecipientV2ParticipantRoles, projectRecipientV2Routes } from './recipientV2.inspect.projection.js';
|
|
16
|
+
import { inspectRecipientV2WorkspaceSurface } from './recipientV2.inspect.workspaces.js';
|
|
17
|
+
|
|
18
|
+
export const RECIPIENT_V2_TOPOLOGY_INSPECTION_SCHEMA_ID = 'tiinex.portable.recipient-facing-handoff-v2.inspection.v1';
|
|
19
|
+
|
|
20
|
+
export function roundTripRecipientFacingV2Topology(bundle = {}, sourceInspection = null) {
|
|
21
|
+
sourceInspection = sourceInspection || inspectRecipientFacingV2Topology(bundle);
|
|
22
|
+
if (sourceInspection.status !== 'valid') return deepFreeze({ schema: 'tiinex.portable.recipient-facing-handoff-v2.roundtrip.v1', status: 'failed', comparison: 'not-run', inspection: sourceInspection, findings: sourceInspection.findings });
|
|
23
|
+
let zipBytes;
|
|
24
|
+
try { zipBytes = exportFileMapZipUint8Array((bundle.files || []).map((file) => ({ path: String(file.path || ''), data: packageFileBytes(file) })), 'portable.handoff-v2-surface.roundtrip.path.invalid'); }
|
|
25
|
+
catch (error) { return deepFreeze({ schema: 'tiinex.portable.recipient-facing-handoff-v2.roundtrip.v1', status: 'failed', comparison: 'not-run', inspection: sourceInspection, findings: Object.freeze([finding('error', 'portable.handoff-v2-surface.roundtrip.serialize-failed', 'Recipient-facing v2 serialization failed.', { detail: String(error?.message || error || '') })]) }); }
|
|
26
|
+
const parsed = inspectStoredWorkspaceArchive(zipBytes, { ownedBytes: true });
|
|
27
|
+
if (parsed.state !== 'qualified') return deepFreeze({ schema: 'tiinex.portable.recipient-facing-handoff-v2.roundtrip.v1', status: 'failed', comparison: 'mismatch', inspection: sourceInspection, findings: Object.freeze((parsed.findings || []).map((item) => finding('error', 'portable.handoff-v2-surface.roundtrip.zip-invalid', item.message || 'Serialized recipient-facing v2 ZIP is invalid.', { cause: item.code || '' }))) });
|
|
28
|
+
const files = (parsed.entries || []).map((entry) => Object.freeze({ path: entry.path, data: entry.data, bytes: entry.bytes, sha256: entry.sha256 }));
|
|
29
|
+
const verifiedPhysicalIdentityByPath = new Map((parsed.entries || []).map((entry) => [String(entry.path || ''), Object.freeze({ data: entry.data, bytes: entry.bytes, sha256: entry.sha256 })]));
|
|
30
|
+
const reinspection = inspectRecipientFacingV2Topology({ ...bundle, files: Object.freeze(files) }, { verifiedPhysicalIdentityByPath });
|
|
31
|
+
const sourceManifestSha256 = String(sourceInspection.transportManifest?.sha256 || '');
|
|
32
|
+
const receivedManifestSha256 = String(reinspection.transportManifest?.sha256 || '');
|
|
33
|
+
const manifestComparisonAvailable = sourceInspection.transportManifest?.state === 'valid' && reinspection.transportManifest?.state === 'valid' && sourceManifestSha256 && receivedManifestSha256;
|
|
34
|
+
const comparison = manifestComparisonAvailable
|
|
35
|
+
? (sourceManifestSha256 === receivedManifestSha256 ? 'match' : 'mismatch')
|
|
36
|
+
: compareRecipientFileBytes(bundle.files || [], files);
|
|
37
|
+
const status = comparison === 'match' && reinspection.status === 'valid' ? 'passed' : 'failed';
|
|
38
|
+
return deepFreeze({ schema: 'tiinex.portable.recipient-facing-handoff-v2.roundtrip.v1', status, comparison, bytes: zipBytes.byteLength, inspection: reinspection, findings: reinspection.findings });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function inspectRecipientFacingV2Topology(bundle = {}, options = {}) {
|
|
42
|
+
const files = Array.isArray(bundle.files) ? bundle.files : [];
|
|
43
|
+
if (isRecipientV2PackageV1Surface(files)) return inspectRecipientFacingV2PackageV1(bundle, options);
|
|
44
|
+
if (isRecipientV2ArtifactFirstPhase1Surface(files)) return inspectRecipientFacingV2ArtifactFirstPhase1(bundle, options);
|
|
45
|
+
const findings = [];
|
|
46
|
+
const index = indexRecipientFiles(files, findings);
|
|
47
|
+
const forbidden = files.filter((file) => isForbiddenLegacyV2Path(file.path));
|
|
48
|
+
for (const file of forbidden) findings.push(finding('error', 'portable.handoff-v2-surface.legacy-envelope-exposed', 'Recipient-facing v2 package exposes a rejected legacy control/envelope path.', { path: file.path || '' }));
|
|
49
|
+
for (const file of files) if (String(file.path || '').includes('/')) findings.push(finding('error', 'portable.handoff-v2-surface.path-nonflat', 'Recipient-facing v2 package root must be flat.', { path: file.path || '' }));
|
|
50
|
+
|
|
51
|
+
const transportManifest = inspectRecipientV2TransportManifest(files, { verifiedPhysicalIdentityByPath: options.verifiedPhysicalIdentityByPath });
|
|
52
|
+
if (transportManifest.state === 'invalid') findings.push(...transportManifest.findings);
|
|
53
|
+
if (transportManifest.state === 'valid' && String(transportManifest.manifest?.format || '') !== RECIPIENT_V2_FORMAT_ID) findings.push(finding('error', 'portable.handoff-v2-transport.manifest.format-mismatch', 'Recipient-v2 transport manifest declares an unsupported carrier format.', { observed: String(transportManifest.manifest?.format || ''), expected: RECIPIENT_V2_FORMAT_ID }));
|
|
54
|
+
const generatedFiles = [];
|
|
55
|
+
const generatedFacts = new Map();
|
|
56
|
+
const untypedMarkdown = [];
|
|
57
|
+
for (const file of files) {
|
|
58
|
+
if (!/\.md$/i.test(String(file.path || ''))) continue;
|
|
59
|
+
const facts = recipientV2FactsForFile(file, transportManifest.state === 'absent' ? null : transportManifest);
|
|
60
|
+
if (facts) { generatedFiles.push(file); generatedFacts.set(String(file.path || ''), facts); }
|
|
61
|
+
else untypedMarkdown.push(file);
|
|
62
|
+
}
|
|
63
|
+
const resolveParent = buildPackageLocalParentResolver(index);
|
|
64
|
+
const generatedArtifacts = generatedFiles.map((file) => inspectRecipientV2Artifact(file, { facts: generatedFacts.get(String(file.path || '')) || null, resolveParent }));
|
|
65
|
+
for (const artifact of generatedArtifacts) findings.push(...artifact.findings);
|
|
66
|
+
for (const file of untypedMarkdown) findings.push(finding('error', 'portable.handoff-v2-surface.markdown-unqualified', 'Recipient-facing v2 root contains Markdown that is not one generated qualified package-local Tiinex artifact.', { path: file.path || '' }));
|
|
67
|
+
|
|
68
|
+
const packageRoots = generatedArtifacts.filter((item) => item.schemaId === 'tiinex.pointer.v1' && item.facts?.role === 'package-root');
|
|
69
|
+
const rootArtifact = packageRoots.length === 1 ? packageRoots[0] : null;
|
|
70
|
+
if (packageRoots.length !== 1) findings.push(finding('error', 'portable.handoff-v2-surface.package-root.unresolvable', 'Recipient-facing v2 package must expose exactly one package-local Tiinex root artifact.', { count: packageRoots.length }));
|
|
71
|
+
else {
|
|
72
|
+
if (rootArtifact.conformance?.parentContinuity?.parentDeclared) findings.push(finding('error', 'portable.handoff-v2-surface.package-root.parent-invalid', 'Package-local root artifact must not declare a Parent.', { path: rootArtifact.path }));
|
|
73
|
+
if (String(rootArtifact.facts?.entryArtifactPath || '') !== RECIPIENT_V2_READ_PATH) findings.push(finding('error', 'portable.handoff-v2-surface.package-root.entry-mismatch', 'Package-local root must explicitly declare the fixed recipient entry artifact.', { path: rootArtifact.path, expectedEntry: RECIPIENT_V2_READ_PATH, observedEntry: String(rootArtifact.facts?.entryArtifactPath || '') }));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const readArtifact = generatedArtifacts.find((item) => item.path === RECIPIENT_V2_READ_PATH) || null;
|
|
77
|
+
if (!readArtifact) findings.push(finding('error', 'portable.handoff-v2-surface.read-missing', 'Recipient-facing v2 package is missing its qualified READ-BEFORE Pointer.'));
|
|
78
|
+
else {
|
|
79
|
+
if (readArtifact.schemaId !== 'tiinex.pointer.v1' || readArtifact.facts?.role !== 'recovery-orientation' || readArtifact.facts?.format !== RECIPIENT_V2_FORMAT_ID) findings.push(finding('error', 'portable.handoff-v2-surface.read-role-invalid', 'READ-BEFORE artifact does not identify the supported flat recipient-facing v2 surface.', { path: readArtifact.path || '' }));
|
|
80
|
+
if (String(readArtifact.facts?.entryArtifactPath || '') !== RECIPIENT_V2_READ_PATH) findings.push(finding('error', 'portable.handoff-v2-surface.read.entry-mismatch', 'READ-BEFORE artifact must explicitly identify itself as the fixed recipient entry artifact.', { path: readArtifact.path || '', expectedEntry: RECIPIENT_V2_READ_PATH, observedEntry: String(readArtifact.facts?.entryArtifactPath || '') }));
|
|
81
|
+
if (String(readArtifact.facts?.routeSelectionAuthority || '') !== RECIPIENT_V2_ROUTE_SELECTION_AUTHORITY) findings.push(finding('error', 'portable.handoff-v2-surface.read.route-selection-authority-missing', 'READ-BEFORE artifact must declare that recipient routing is selected by one exact package-local Handoff Route Pointer supplied by the outer invocation.', { path: readArtifact.path || '' }));
|
|
82
|
+
if (readArtifact.facts?.siblingRouteInference !== RECIPIENT_V2_SIBLING_ROUTE_INFERENCE) findings.push(finding('error', 'portable.handoff-v2-surface.read.sibling-route-inference-enabled', 'READ-BEFORE artifact must fail closed rather than infer among sibling Handoff routes.', { path: readArtifact.path || '' }));
|
|
83
|
+
if (rootArtifact && parentTrace(readArtifact) !== rootArtifact.path) findings.push(finding('error', 'portable.handoff-v2-surface.read.parent-mismatch', 'READ-BEFORE artifact must be a direct child of the package-local root.', { path: readArtifact.path, expectedParent: rootArtifact.path, observedParent: parentTrace(readArtifact) }));
|
|
84
|
+
}
|
|
85
|
+
const detected = Boolean(rootArtifact || readArtifact?.facts?.format === RECIPIENT_V2_FORMAT_ID || transportManifest.state !== 'absent' || forbidden.length);
|
|
86
|
+
|
|
87
|
+
const workspaceSurface = inspectRecipientV2WorkspaceSurface({ generatedArtifacts, rootArtifact, index, findings, transportManifest });
|
|
88
|
+
const {
|
|
89
|
+
routePointers,
|
|
90
|
+
endpointRolePointers,
|
|
91
|
+
participantRolePointers,
|
|
92
|
+
bootstrap,
|
|
93
|
+
workspaceParts,
|
|
94
|
+
workspaceDescriptors,
|
|
95
|
+
virtualWorkspaceTargetFiles,
|
|
96
|
+
archiveClaims,
|
|
97
|
+
caches,
|
|
98
|
+
virtualCache
|
|
99
|
+
} = workspaceSurface;
|
|
100
|
+
|
|
101
|
+
for (const file of files) {
|
|
102
|
+
const path = String(file.path || '');
|
|
103
|
+
if (/\.zip$/i.test(path) && (archiveClaims.get(path) || []).length !== 1) findings.push(finding('error', 'portable.handoff-v2-surface.payload-unowned', 'Every visible ZIP companion must be owned by exactly one qualified package-local Markdown lineage node.', { path, claims: (archiveClaims.get(path) || []).length }));
|
|
104
|
+
if (!/\.(?:md|zip)$/i.test(path) && path !== RECIPIENT_V2_TRANSPORT_MANIFEST_PATH) findings.push(finding('error', 'portable.handoff-v2-surface.root-file-kind-invalid', 'Recipient-facing v2 root may expose only qualified Tiinex Markdown artifacts, explicitly referenced ZIP companions, and the single transport-owned manifest.', { path }));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const routeWorkspaceMaterialized = routePointers.flatMap((pointer) => {
|
|
108
|
+
const facts = pointer.facts || {};
|
|
109
|
+
return (Array.isArray(facts.requiredContextBindings) ? facts.requiredContextBindings : []).map((binding) => Object.freeze({
|
|
110
|
+
requirementId: String(binding.requirementId || ''),
|
|
111
|
+
classification: 'required',
|
|
112
|
+
referenceTarget: String(binding.referenceTarget || ''),
|
|
113
|
+
routeWorkspaceId: String(facts.workspaceId || ''),
|
|
114
|
+
routePath: String(facts.workspaceRelativeHandoffPath || ''),
|
|
115
|
+
carrierKind: 'workspace-archive-entry',
|
|
116
|
+
workspaceId: String(binding.workspaceId || ''),
|
|
117
|
+
workspaceRelativePath: String(binding.workspaceRelativePath || ''),
|
|
118
|
+
bytes: Number(binding.bytes || 0),
|
|
119
|
+
sha256: String(binding.sha256 || '')
|
|
120
|
+
}));
|
|
121
|
+
});
|
|
122
|
+
const descriptor = deepFreeze({
|
|
123
|
+
schema: 'tiinex.transport.handoff-material-closure-descriptor.v2', version: 2,
|
|
124
|
+
workspaceMaterializations: Object.freeze(workspaceDescriptors.map((item) => item.workspace)),
|
|
125
|
+
workspaceArchiveBindings: Object.freeze(workspaceDescriptors.map((item) => item.binding)),
|
|
126
|
+
materialized: Object.freeze([...virtualCache.materialized, ...routeWorkspaceMaterialized]),
|
|
127
|
+
requirements: Object.freeze({ required: Object.freeze([]), reference: Object.freeze([]), endpointRoles: Object.freeze([]), participantRoles: Object.freeze([]), dependencies: Object.freeze([]) })
|
|
128
|
+
});
|
|
129
|
+
const semanticBundle = { ...bundle, files: Object.freeze([...files, ...virtualWorkspaceTargetFiles, ...virtualCache.files]) };
|
|
130
|
+
const workspaceByteProvider = buildQualifiedRecipientV2WorkspaceByteProvider(workspaceParts);
|
|
131
|
+
findings.push(...workspaceByteProvider.findings);
|
|
132
|
+
for (const workspace of workspaceParts) {
|
|
133
|
+
const providerWorkspace = handoffWorkspaceProviderForId(workspaceByteProvider, workspace.workspaceId);
|
|
134
|
+
if (providerWorkspace.state !== 'qualified') findings.push(finding('error', 'portable.handoff-v2-surface.workspace-provider.unqualified', 'Visible package-local Workspace node plus exact archive/source Workspace bytes did not requalify as one complete Workspace provider.', { workspaceId: workspace.workspaceId, reasons: providerWorkspace.reasons || [] }));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const routeSpecs = routePointers.map((pointer) => ({ workspaceId: String(pointer.facts?.workspaceId || ''), path: String(pointer.facts?.workspaceRelativeHandoffPath || ''), purpose: '' }));
|
|
138
|
+
const carrierLineage = rootArtifact?.facts?.carrierLineage || legacyCarrierLineageFromRoutePointers(routePointers);
|
|
139
|
+
const carrierProjection = buildHandoffCarrierProjection({ bundle: semanticBundle, descriptor, workspaceByteProvider, carrierLineage, routes: routeSpecs });
|
|
140
|
+
if (carrierProjection.status !== 'ready') findings.push(finding('error', 'portable.handoff-v2-surface.routes.unqualified', 'Recipient-facing route Pointers do not independently resolve to qualified carried Handoff bytes.', { causes: carrierProjection.findings || [] }));
|
|
141
|
+
inspectRoutePointers(routePointers, carrierProjection, workspaceParts, endpointRolePointers, participantRolePointers, index, findings);
|
|
142
|
+
for (const route of carrierProjection.routes || []) if (route.requiredClosure?.state !== 'qualified') findings.push(finding('error', 'portable.handoff-v2-surface.required-closure.unqualified', 'Selected Handoff Required Context does not resolve entirely to exact Workspace/archive or qualified cache bytes.', { routeId: route.id || '', requirements: route.requiredClosure?.requirements || [] }));
|
|
143
|
+
if (!routePointers.length) findings.push(finding('error', 'portable.handoff-v2-surface.routes.missing', 'Recipient-facing v2 package requires at least one qualified Handoff route Pointer.'));
|
|
144
|
+
if (!workspaceParts.length) findings.push(finding('error', 'portable.handoff-v2-surface.workspaces.missing', 'Recipient-facing v2 package requires at least one qualified package-local Workspace node/archive pair.'));
|
|
145
|
+
|
|
146
|
+
const coldConsumerProjection = recipientColdProjection(carrierProjection, RECIPIENT_V2_READ_PATH);
|
|
147
|
+
const finalFindings = dedupeFindings(findings);
|
|
148
|
+
const status = finalFindings.some((item) => item.severity === 'error') ? 'invalid' : 'valid';
|
|
149
|
+
return deepFreeze({
|
|
150
|
+
schema: RECIPIENT_V2_TOPOLOGY_INSPECTION_SCHEMA_ID,
|
|
151
|
+
detected,
|
|
152
|
+
status,
|
|
153
|
+
format: detected ? RECIPIENT_V2_FORMAT_ID : '',
|
|
154
|
+
rootArtifact: rootArtifact ? Object.freeze({ path: rootArtifact.path, schemaId: rootArtifact.schemaId, sha256: rootArtifact.sha256, carrierLineage: carrierProjection.lineage || null }) : null,
|
|
155
|
+
readArtifact,
|
|
156
|
+
workspaces: Object.freeze(workspaceParts.map((item) => Object.freeze({ workspaceId: item.workspaceId, coverage: item.representation.coverage === 'bounded' ? 'bounded' : 'complete', workspaceArtifactPath: item.artifact.path, workspaceRepresentationArtifactPath: item.representationArtifact.path, workspacePayloadArtifactPath: item.payloadArtifact.path, workspaceArchivePath: item.archiveFile.path, sourceWorkspaceTargetInnerPath: item.representation.workspaceArtifactInnerPath, sourceWorkspaceTargetSha256: item.targetFile.sha256 }))),
|
|
157
|
+
routes: projectRecipientV2Routes(routePointers, endpointRolePointers, participantRolePointers),
|
|
158
|
+
endpointRoles: projectRecipientV2EndpointRoles(endpointRolePointers),
|
|
159
|
+
participantRoles: projectRecipientV2ParticipantRoles(participantRolePointers),
|
|
160
|
+
caches: Object.freeze(caches.map((cache) => Object.freeze({ workspaceId: String(cache.facts?.workspaceId || ''), artifactPath: cache.artifact.path, archivePath: cache.file.path, materials: cache.facts.materials || [] }))),
|
|
161
|
+
bootstrapInspection: bootstrap?.inspection || null,
|
|
162
|
+
transportManifest: transportManifest.state === 'absent' ? null : Object.freeze({ state: transportManifest.state, path: RECIPIENT_V2_TRANSPORT_MANIFEST_PATH, sha256: transportManifest.file ? sha256Hex(packageFileBytes(transportManifest.file)) : '', format: String(transportManifest.manifest?.format || '') }),
|
|
163
|
+
artifactFacts: Object.freeze(generatedArtifacts.map((item) => Object.freeze({ path: item.path, facts: item.facts }))),
|
|
164
|
+
descriptor,
|
|
165
|
+
workspaceByteProvider,
|
|
166
|
+
carrierProjection,
|
|
167
|
+
coldConsumerProjection,
|
|
168
|
+
findings: Object.freeze(finalFindings),
|
|
169
|
+
findingSummary: Object.freeze({ errors: finalFindings.filter((item) => item.severity === 'error').length, findings: finalFindings.length }),
|
|
170
|
+
boundary: 'Read-only qualification of the flat recipient-facing v2 carrier. The package-local numeric tree must mirror explicit Parent continuity; exact durable Workspace and Handoff source bytes remain independently qualified inside their owned archive representations.'
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
function compareRecipientFileBytes(sourceFiles = [], receivedFiles = []) {
|
|
177
|
+
const identityMap = (files) => new Map(files.map((file) => {
|
|
178
|
+
const data = packageFileBytes(file);
|
|
179
|
+
return [String(file.path || ''), `${data.byteLength}:${sha256Hex(data)}`];
|
|
180
|
+
}));
|
|
181
|
+
const source = identityMap(sourceFiles);
|
|
182
|
+
const received = identityMap(receivedFiles);
|
|
183
|
+
return source.size === received.size && [...source].every(([path, identity]) => received.get(path) === identity) ? 'match' : 'mismatch';
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function legacyCarrierLineageFromRoutePointers(routePointers = []) {
|
|
187
|
+
const dimensions = [...new Set(routePointers.map((pointer) => {
|
|
188
|
+
const name = String(pointer.facts?.workspaceRelativeHandoffPath || '').replace(/\\/g, '/').split('/').pop() || '';
|
|
189
|
+
return String(name.match(/^(\d{3}(?:-\d+)*)-/)?.[1] || '');
|
|
190
|
+
}).filter(Boolean))];
|
|
191
|
+
if (dimensions.length !== 1) return null;
|
|
192
|
+
const dimension = dimensions[0];
|
|
193
|
+
return Object.freeze({ mode: dimension.includes('-') ? 'continue' : 'root', dimension, checkpointKind: dimension.includes('-') ? 'progression' : 'major' });
|
|
194
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { sha256Hex, utf8Bytes } from '../../../export/package.bytes.js';
|
|
2
|
+
|
|
3
|
+
export function boundedRecipientToken(value = '') {
|
|
4
|
+
const raw = String(value || '');
|
|
5
|
+
const token = raw.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');
|
|
6
|
+
if (!token) return 'material';
|
|
7
|
+
if (token.length <= 100) return token;
|
|
8
|
+
return `${token.slice(0, 87)}-${sha256Hex(utf8Bytes(raw)).slice(0, 12)}`;
|
|
9
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { parentTrace } from './recipientV2.lineage.js';
|
|
2
|
+
|
|
3
|
+
export function projectRecipientV2Routes(routePointers = [], endpointPointers = [], participantPointers = []) {
|
|
4
|
+
return Object.freeze(routePointers.map((item) => Object.freeze({
|
|
5
|
+
pointerPath: item.path,
|
|
6
|
+
workspaceId: String(item.facts?.workspaceId || ''),
|
|
7
|
+
workspaceRelativeHandoffPath: String(item.facts?.workspaceRelativeHandoffPath || ''),
|
|
8
|
+
endpointRolePointers: Object.freeze(rolePointerAncestors(item, endpointPointers, participantPointers).filter((path) => endpointPointers.some((pointer) => pointer.path === path))),
|
|
9
|
+
participantRolePointers: Object.freeze(rolePointerAncestors(item, endpointPointers, participantPointers).filter((path) => participantPointers.some((pointer) => pointer.path === path)))
|
|
10
|
+
})));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function projectRecipientV2EndpointRoles(pointers = []) {
|
|
14
|
+
return Object.freeze(pointers.map((item) => Object.freeze({
|
|
15
|
+
pointerPath: item.path,
|
|
16
|
+
workspaceId: String(item.facts?.workspaceId || ''),
|
|
17
|
+
routeId: String(item.facts?.routeId || ''),
|
|
18
|
+
requirementId: String(item.facts?.endpointRequirementId || ''),
|
|
19
|
+
endpointParty: String(item.facts?.endpointParty || ''),
|
|
20
|
+
roleLabelHint: String(item.facts?.roleLabelHint || ''),
|
|
21
|
+
referenceTarget: String(item.facts?.referenceTarget || ''),
|
|
22
|
+
targetCarrierKind: String(item.facts?.targetCarrierKind || ''),
|
|
23
|
+
targetWorkspaceId: String(item.facts?.targetWorkspaceId || ''),
|
|
24
|
+
archivePath: String(item.facts?.archivePath || ''),
|
|
25
|
+
targetInnerPath: String(item.facts?.targetInnerPath || item.facts?.targetArchiveEntry || ''),
|
|
26
|
+
targetArchiveEntry: String(item.facts?.targetArchiveEntry || ''),
|
|
27
|
+
targetBytes: Number(item.facts?.targetBytes || 0),
|
|
28
|
+
targetSha256: String(item.facts?.targetSha256 || '')
|
|
29
|
+
})));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function projectRecipientV2ParticipantRoles(pointers = []) {
|
|
33
|
+
return Object.freeze(pointers.map((item) => Object.freeze({
|
|
34
|
+
pointerPath: item.path,
|
|
35
|
+
workspaceId: String(item.facts?.workspaceId || ''),
|
|
36
|
+
routeId: String(item.facts?.routeId || ''),
|
|
37
|
+
roleLabelHint: String(item.facts?.roleLabelHint || ''),
|
|
38
|
+
referenceTarget: String(item.facts?.referenceTarget || ''),
|
|
39
|
+
targetCarrierKind: String(item.facts?.targetCarrierKind || ''),
|
|
40
|
+
targetWorkspaceId: String(item.facts?.targetWorkspaceId || ''),
|
|
41
|
+
targetInnerPath: String(item.facts?.targetInnerPath || item.facts?.targetArchiveEntry || ''),
|
|
42
|
+
targetSha256: String(item.facts?.targetSha256 || '')
|
|
43
|
+
})));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function rolePointerAncestors(routePointer, endpointPointers = [], participantPointers = []) {
|
|
47
|
+
const byPath = new Map([...endpointPointers, ...participantPointers].map((item) => [String(item.path || ''), item]));
|
|
48
|
+
const out = [];
|
|
49
|
+
const seen = new Set();
|
|
50
|
+
let parent = parentTrace(routePointer);
|
|
51
|
+
while (byPath.has(parent) && !seen.has(parent)) {
|
|
52
|
+
seen.add(parent);
|
|
53
|
+
const pointer = byPath.get(parent);
|
|
54
|
+
out.unshift(pointer.path);
|
|
55
|
+
parent = parentTrace(pointer);
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
}
|