@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,123 @@
|
|
|
1
|
+
import { finalizeFile } from '../../../export/package.fileMap.js';
|
|
2
|
+
import { packageFileByteView, packageFileBytes, sha256Hex } from '../../../export/package.bytes.js';
|
|
3
|
+
import { parseRecipientV2Facts } from './recipientV2.artifacts.js';
|
|
4
|
+
|
|
5
|
+
export const RECIPIENT_V2_TRANSPORT_MANIFEST_PATH = 'tiinex-recipient-v2.transport.json';
|
|
6
|
+
export const RECIPIENT_V2_TRANSPORT_MANIFEST_SCHEMA_ID = 'tiinex.transport.recipient-v2.manifest.v1';
|
|
7
|
+
|
|
8
|
+
export function recipientV2TransportFacts(role = '', facts = {}) {
|
|
9
|
+
return Object.freeze({ factsFormat: 'portable-recipient-v2', factsVersion: 1, role: String(role || ''), ...(facts || {}) });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function buildRecipientV2TransportManifestFile(files = [], input = {}) {
|
|
13
|
+
const entries = [...files]
|
|
14
|
+
.filter((file) => String(file.path || '') !== RECIPIENT_V2_TRANSPORT_MANIFEST_PATH)
|
|
15
|
+
.map((file) => {
|
|
16
|
+
const data = packageFileByteView(file);
|
|
17
|
+
return Object.freeze({
|
|
18
|
+
path: String(file.path || ''),
|
|
19
|
+
bytes: data.byteLength,
|
|
20
|
+
sha256: reusableFinalizedIdentity(file, data) || sha256Hex(data),
|
|
21
|
+
kind: String(file.kind || ''),
|
|
22
|
+
mediaType: String(file.mediaType || ''),
|
|
23
|
+
...(file.transportFacts ? { facts: file.transportFacts } : {})
|
|
24
|
+
});
|
|
25
|
+
})
|
|
26
|
+
.sort((a, b) => a.path.localeCompare(b.path));
|
|
27
|
+
const manifest = Object.freeze({
|
|
28
|
+
schema: RECIPIENT_V2_TRANSPORT_MANIFEST_SCHEMA_ID,
|
|
29
|
+
version: 1,
|
|
30
|
+
format: String(input.format || ''),
|
|
31
|
+
packageRootPath: String(input.packageRootPath || ''),
|
|
32
|
+
entryArtifactPath: String(input.entryArtifactPath || ''),
|
|
33
|
+
boundary: 'Transport-owned recipient-v2 topology and exact byte map. This control surface is not a Tiinex semantic artifact and does not create Parent, Workspace, Handoff, authorship, or publication authority.',
|
|
34
|
+
entries: Object.freeze(entries)
|
|
35
|
+
});
|
|
36
|
+
return finalizeFile({
|
|
37
|
+
path: RECIPIENT_V2_TRANSPORT_MANIFEST_PATH,
|
|
38
|
+
kind: 'handoff-transport-manifest',
|
|
39
|
+
logicalKind: 'recipient-v2-transport-control',
|
|
40
|
+
mediaType: 'application/json',
|
|
41
|
+
content: `${stableJson(manifest)}\n`,
|
|
42
|
+
boundary: manifest.boundary
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function inspectRecipientV2TransportManifest(files = [], options = {}) {
|
|
47
|
+
const findings = [];
|
|
48
|
+
const candidates = files.filter((file) => String(file.path || '') === RECIPIENT_V2_TRANSPORT_MANIFEST_PATH);
|
|
49
|
+
if (!candidates.length) return Object.freeze({ state: 'absent', file: null, manifest: null, factsByPath: new Map(), identityByPath: new Map(), findings: Object.freeze([]) });
|
|
50
|
+
if (candidates.length !== 1) return Object.freeze({ state: 'invalid', file: null, manifest: null, factsByPath: new Map(), identityByPath: new Map(), findings: Object.freeze([finding('error', 'portable.handoff-v2-transport.manifest.duplicate', 'Recipient-v2 transport manifest must occur exactly once.', { count: candidates.length })]) });
|
|
51
|
+
const file = candidates[0];
|
|
52
|
+
let manifest;
|
|
53
|
+
try { manifest = JSON.parse(decodeUtf8(packageFileBytes(file))); }
|
|
54
|
+
catch { return Object.freeze({ state: 'invalid', file, manifest: null, factsByPath: new Map(), identityByPath: new Map(), findings: Object.freeze([finding('error', 'portable.handoff-v2-transport.manifest.parse-failed', 'Recipient-v2 transport manifest is not valid JSON.')]) }); }
|
|
55
|
+
if (manifest?.schema !== RECIPIENT_V2_TRANSPORT_MANIFEST_SCHEMA_ID || Number(manifest?.version || 0) !== 1) findings.push(finding('error', 'portable.handoff-v2-transport.manifest.schema-invalid', 'Recipient-v2 transport manifest schema/version is unsupported.'));
|
|
56
|
+
if (!manifest?.format || !manifest?.packageRootPath || !manifest?.entryArtifactPath) findings.push(finding('error', 'portable.handoff-v2-transport.manifest.identity-incomplete', 'Recipient-v2 transport manifest is missing format/root/entry identity.'));
|
|
57
|
+
const physical = new Map();
|
|
58
|
+
for (const candidate of files) {
|
|
59
|
+
const path = String(candidate.path || '');
|
|
60
|
+
if (!path || path === RECIPIENT_V2_TRANSPORT_MANIFEST_PATH) continue;
|
|
61
|
+
const list = physical.get(path) || [];
|
|
62
|
+
list.push(candidate);
|
|
63
|
+
physical.set(path, list);
|
|
64
|
+
}
|
|
65
|
+
const declared = new Map();
|
|
66
|
+
const factsByPath = new Map();
|
|
67
|
+
const identityByPath = new Map();
|
|
68
|
+
for (const entry of Array.isArray(manifest?.entries) ? manifest.entries : []) {
|
|
69
|
+
const path = String(entry?.path || '');
|
|
70
|
+
if (!path || declared.has(path)) { findings.push(finding('error', 'portable.handoff-v2-transport.manifest.entry-path-invalid', 'Transport manifest entry path is missing or duplicated.', { path })); continue; }
|
|
71
|
+
declared.set(path, entry);
|
|
72
|
+
const matches = physical.get(path) || [];
|
|
73
|
+
if (matches.length !== 1) { findings.push(finding('error', 'portable.handoff-v2-transport.manifest.entry-unresolved', 'Transport manifest entry does not resolve to exactly one visible carrier.', { path, count: matches.length })); continue; }
|
|
74
|
+
const data = packageFileByteView(matches[0]);
|
|
75
|
+
const observedSha256 = reusableReceivedIdentity(options.verifiedPhysicalIdentityByPath?.get?.(path), data) || sha256Hex(data);
|
|
76
|
+
identityByPath.set(path, Object.freeze({ bytes: data.byteLength, sha256: observedSha256 }));
|
|
77
|
+
if (Number(entry.bytes) !== data.byteLength || String(entry.sha256 || '') !== observedSha256) findings.push(finding('error', 'portable.handoff-v2-transport.manifest.byte-identity-mismatch', 'Transport manifest byte identity does not match the visible carrier.', { path }));
|
|
78
|
+
if (/\.md$/i.test(path)) {
|
|
79
|
+
if (!entry.facts || entry.facts.factsFormat !== 'portable-recipient-v2' || Number(entry.facts.factsVersion || 0) !== 1) findings.push(finding('error', 'portable.handoff-v2-transport.manifest.markdown-facts-missing', 'Every generated recipient-v2 Markdown carrier requires one transport-manifest facts record.', { path }));
|
|
80
|
+
else factsByPath.set(path, Object.freeze({ ...entry.facts }));
|
|
81
|
+
} else if (entry.facts) findings.push(finding('error', 'portable.handoff-v2-transport.manifest.nonmarkdown-facts', 'Transport facts may only annotate generated Markdown carriers.', { path }));
|
|
82
|
+
}
|
|
83
|
+
for (const [path, matches] of physical) {
|
|
84
|
+
if (matches.length !== 1) findings.push(finding('error', 'portable.handoff-v2-transport.manifest.physical-duplicate', 'Visible recipient-v2 carrier path is duplicated.', { path, count: matches.length }));
|
|
85
|
+
if (!declared.has(path)) findings.push(finding('error', 'portable.handoff-v2-transport.manifest.unmapped-carrier', 'Visible recipient-v2 carrier is absent from the transport manifest byte map.', { path }));
|
|
86
|
+
}
|
|
87
|
+
return Object.freeze({ state: findings.some((item) => item.severity === 'error') ? 'invalid' : 'valid', file, manifest: manifest || null, factsByPath, identityByPath, findings: Object.freeze(findings) });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function recipientV2FactsForFile(file = {}, transportInspection = null) {
|
|
91
|
+
const path = String(file?.path || '');
|
|
92
|
+
const manifested = transportInspection?.factsByPath?.get?.(path) || null;
|
|
93
|
+
if (manifested) return manifested;
|
|
94
|
+
if (!/\.md$/i.test(path)) return null;
|
|
95
|
+
return parseRecipientV2Facts(decodeUtf8(packageFileBytes(file)));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function recipientV2FactsIndex(bundle = {}) {
|
|
99
|
+
const files = Array.isArray(bundle.files) ? bundle.files : [];
|
|
100
|
+
const transport = inspectRecipientV2TransportManifest(files);
|
|
101
|
+
const map = new Map();
|
|
102
|
+
for (const file of files) {
|
|
103
|
+
const facts = recipientV2FactsForFile(file, transport.state === 'valid' ? transport : null);
|
|
104
|
+
if (facts) map.set(String(file.path || ''), facts);
|
|
105
|
+
}
|
|
106
|
+
return Object.freeze({ transport, map });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function reusableFinalizedIdentity(file = {}, data = new Uint8Array()) {
|
|
110
|
+
if (!Object.isFrozen(file) || Number(file.bytes) !== data.byteLength) return '';
|
|
111
|
+
const digest = String(file.sha256 || '').toLowerCase();
|
|
112
|
+
return /^[a-f0-9]{64}$/.test(digest) ? digest : '';
|
|
113
|
+
}
|
|
114
|
+
function reusableReceivedIdentity(identity = null, data = new Uint8Array()) {
|
|
115
|
+
if (!identity || identity.data !== data || Number(identity.bytes) !== data.byteLength) return '';
|
|
116
|
+
const digest = String(identity.sha256 || '').toLowerCase();
|
|
117
|
+
return /^[a-f0-9]{64}$/.test(digest) ? digest : '';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function stableJson(value) { return JSON.stringify(sortJson(value)); }
|
|
121
|
+
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])])); }
|
|
122
|
+
function decodeUtf8(data) { try { return new TextDecoder('utf-8', { fatal: true }).decode(data); } catch { return ''; } }
|
|
123
|
+
function finding(severity, code, message, extra = {}) { return Object.freeze({ severity, code, message, ...extra }); }
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { sealC14nV2Self } from '../../../integrity/integrity.c14nV2.js';
|
|
2
|
+
import { C14N_V2_VALIDATOR_TARGET } from '../../../integrity/integrity.methodReference.js';
|
|
3
|
+
|
|
4
|
+
const RECIPIENT_V2_ROOT_SCHEMA_TARGET = 'https://github.com/Tiinex/docs/blob/3988951208eb9a8926e84ab42625d4b42fa00c2d/.topics/.schemas/tiinex.root.v1.schema.md';
|
|
5
|
+
export const RECIPIENT_V2_WORKSPACE_REPRESENTATION_SCHEMA_TARGET = 'https://github.com/Tiinex/docs/blob/0fdce5f265298321a41cd90cf5382bcb6ae31a13/.topics/.schemas/relation/workspace/representation/tiinex.workspace.representation.v1.schema.md';
|
|
6
|
+
|
|
7
|
+
const COMPLETE_CONTRACT = Object.freeze({
|
|
8
|
+
coverage: 'complete',
|
|
9
|
+
representationKind: 'exact-workspace-byte-tree-archive',
|
|
10
|
+
activationRule: 'verified-complete-only',
|
|
11
|
+
coverageRequirement: 'complete',
|
|
12
|
+
selectionRule: 'exactly-one-binding-per-workspace'
|
|
13
|
+
});
|
|
14
|
+
const BOUNDED_CONTRACT = Object.freeze({
|
|
15
|
+
coverage: 'bounded',
|
|
16
|
+
representationKind: 'exact-bounded-workspace-byte-tree-archive',
|
|
17
|
+
activationRule: 'verified-bounded-only',
|
|
18
|
+
coverageRequirement: 'bounded',
|
|
19
|
+
selectionRule: 'explicit-binding-per-bounded-scope'
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export function renderRecipientV2WorkspaceRepresentation(input = {}) {
|
|
23
|
+
const createdAt = normalizeCreatedAt(input.createdAt || '');
|
|
24
|
+
const contract = String(input.coverage || 'complete') === 'bounded' ? BOUNDED_CONTRACT : COMPLETE_CONTRACT;
|
|
25
|
+
const scope = contract.coverage === 'bounded'
|
|
26
|
+
? `\n## Representation Scope\n\n- Scope Basis: exact-representation-entry-set\n- Included Entry Authority: qualified-decoded-entry-set\n- Omitted Entry Meaning: outside-representation-not-absent-from-workspace\n- Source Membership Claim: represented-entries-are-workspace-relative-source-bytes\n- Recovery Closure Boundary: separate-qualified-closure\n`
|
|
27
|
+
: '';
|
|
28
|
+
const unsigned = `# Continuity Context\n\n- Envelope Schema: [tiinex.root.v1](${RECIPIENT_V2_ROOT_SCHEMA_TARGET})\n${renderParentEnvelope(input.parent)}- Current\n - Current Schema: [tiinex.workspace.representation.v1](${RECIPIENT_V2_WORKSPACE_REPRESENTATION_SCHEMA_TARGET})\n - Created At: ${createdAt}\n - Summary: ${String(input.summary || 'Explicit canonical binding between one package-local Workspace artifact and one exact Workspace archive External Payload.')}\n\n---\n\n# ${String(input.title || 'Workspace Representation')}\n\n## Representation Binding\n\n- Workspace Artifact: [${String(input.workspaceLabel || 'Workspace artifact')}](${String(input.workspaceArtifactPath || '')})\n- Representation Payload: [${String(input.payloadLabel || 'Workspace representation payload')}](${String(input.payloadArtifactPath || '')})\n- Representation Kind: ${contract.representationKind}\n- Coverage: ${contract.coverage}\n- Binding State: ${String(input.bindingState || 'verified')}\n${scope}\n## Representation Correlation\n\n- Workspace Tree Root: ${String(input.workspaceTreeRoot || '.')}\n- Workspace Artifact Inner Path: ${String(input.workspaceArtifactInnerPath || '')}\n- Archive Entry Root: ${String(input.archiveEntryRoot || '.')}\n- Path Mapping: ${String(input.pathMapping || 'identity-relative-paths')}\n- Collision Policy: reject-ambiguous-or-unsafe-paths\n- Decoder Requirement: ${String(input.decoderRequirement || 'deterministic stored ZIP with safe-entry validation')}\n${input.mappingManifest ? `- Mapping Manifest: [Mapping Manifest](${String(input.mappingManifest)})\n` : ''}${input.entryIntegrityManifest ? `- Entry Integrity Manifest: [Entry Integrity Manifest](${String(input.entryIntegrityManifest)})\n` : ''}\n## Provider Qualification\n\n- Activation Rule: ${contract.activationRule}\n- Payload Integrity Requirement: verified-exact-payload-bytes\n- Coverage Requirement: ${contract.coverageRequirement}\n- Staleness Rule: requalify-on-binding-relevant-change\n- Selection Rule: ${contract.selectionRule}\n- Multi-Workspace Isolation: independent-binding-closure\n\n## Relation Boundary\n\n- Parent Boundary: neither endpoint becomes Parent through this representation relation\n- Workspace Identity Boundary: the referenced Workspace artifact remains the semantic Workspace identity\n- Payload Identity Boundary: the referenced External Payload owns archive identity and exact payload-byte integrity\n- Transport Boundary: package location, archive adjacency, repository transport, detached Parent/recovery closure, and decoder success are not binding authority\n- Outer Integrity Boundary: package-wide exact-file/tamper authority remains separately owned\n\n## Interpretation Limits\n\n- Does Not Prove: ${contract.coverage === 'bounded' ? 'whole-Workspace completeness, absence of omitted source paths, ' : ''}semantic correctness, provenance, authorship, acceptance, completion, source identity, permission, consent, or truth\n- Must Not Be Used As: ${contract.coverage === 'bounded' ? 'a complete Workspace snapshot, ' : ''}a replacement for Workspace identity, External Payload authority, Parent continuity, repository transport, preservation, Handoff state, or package-wide integrity authority\n\n## Evidence Basis\n\nProvider activation must requalify this visible binding, its explicit Workspace and External Payload endpoints, the exact payload bytes, decoder/mapping safety, bound Workspace inner entry, and ${contract.coverage === 'bounded' ? 'exact bounded representation entry set. Detached recovery closure is qualified separately and does not enter representation scope.' : 'complete archive entry set.'} Transport facts may detect tampering but are not semantic binding authority.\n\n---\n\n# Continuity Integrity\n\n${renderParentIntegrity(input.parent)}- [sha256-base64url-c14n-v2](${C14N_V2_VALIDATOR_TARGET})\n - Towards: self\n - Value: pending\n`;
|
|
29
|
+
return seal(unsigned);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function parseRecipientV2WorkspaceRepresentation(markdown = '') {
|
|
33
|
+
const binding = sectionText(markdown, 'Representation Binding');
|
|
34
|
+
const scope = sectionText(markdown, 'Representation Scope');
|
|
35
|
+
const correlation = sectionText(markdown, 'Representation Correlation');
|
|
36
|
+
const qualification = sectionText(markdown, 'Provider Qualification');
|
|
37
|
+
return Object.freeze({
|
|
38
|
+
workspaceArtifactPath: markdownTarget(fieldValue(binding, 'Workspace Artifact')),
|
|
39
|
+
payloadArtifactPath: markdownTarget(fieldValue(binding, 'Representation Payload')),
|
|
40
|
+
representationKind: fieldValue(binding, 'Representation Kind'),
|
|
41
|
+
coverage: fieldValue(binding, 'Coverage'),
|
|
42
|
+
bindingState: fieldValue(binding, 'Binding State'),
|
|
43
|
+
scopeBasis: fieldValue(scope, 'Scope Basis'),
|
|
44
|
+
includedEntryAuthority: fieldValue(scope, 'Included Entry Authority'),
|
|
45
|
+
omittedEntryMeaning: fieldValue(scope, 'Omitted Entry Meaning'),
|
|
46
|
+
sourceMembershipClaim: fieldValue(scope, 'Source Membership Claim'),
|
|
47
|
+
recoveryClosureBoundary: fieldValue(scope, 'Recovery Closure Boundary'),
|
|
48
|
+
workspaceTreeRoot: fieldValue(correlation, 'Workspace Tree Root'),
|
|
49
|
+
workspaceArtifactInnerPath: fieldValue(correlation, 'Workspace Artifact Inner Path'),
|
|
50
|
+
archiveEntryRoot: fieldValue(correlation, 'Archive Entry Root'),
|
|
51
|
+
pathMapping: fieldValue(correlation, 'Path Mapping'),
|
|
52
|
+
collisionPolicy: fieldValue(correlation, 'Collision Policy'),
|
|
53
|
+
decoderRequirement: fieldValue(correlation, 'Decoder Requirement'),
|
|
54
|
+
mappingManifest: markdownTarget(fieldValue(correlation, 'Mapping Manifest')),
|
|
55
|
+
entryIntegrityManifest: markdownTarget(fieldValue(correlation, 'Entry Integrity Manifest')),
|
|
56
|
+
activationRule: fieldValue(qualification, 'Activation Rule'),
|
|
57
|
+
payloadIntegrityRequirement: fieldValue(qualification, 'Payload Integrity Requirement'),
|
|
58
|
+
coverageRequirement: fieldValue(qualification, 'Coverage Requirement'),
|
|
59
|
+
stalenessRule: fieldValue(qualification, 'Staleness Rule'),
|
|
60
|
+
selectionRule: fieldValue(qualification, 'Selection Rule'),
|
|
61
|
+
multiWorkspaceIsolation: fieldValue(qualification, 'Multi-Workspace Isolation')
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function parseRecipientV2ExternalPayload(markdown = '') {
|
|
66
|
+
const identity = sectionText(markdown, 'Payload Identity');
|
|
67
|
+
const location = sectionText(markdown, 'Payload Location');
|
|
68
|
+
const integrity = sectionText(markdown, 'Integrity Reference');
|
|
69
|
+
return Object.freeze({
|
|
70
|
+
payloadRole: fieldValue(identity, 'Payload Role'),
|
|
71
|
+
workspaceId: fieldValue(identity, 'Workspace Id'),
|
|
72
|
+
mediaType: fieldValue(identity, 'Media Type'),
|
|
73
|
+
format: fieldValue(identity, 'Format'),
|
|
74
|
+
bytes: Number(fieldValue(identity, 'Byte Size') || 0),
|
|
75
|
+
location: markdownTarget(fieldValue(location, 'Location')),
|
|
76
|
+
integrityStatus: fieldValue(integrity, 'Integrity Status'),
|
|
77
|
+
integrityMethod: fieldValue(integrity, 'Integrity Method'),
|
|
78
|
+
integrityValue: fieldValue(integrity, 'Integrity Value'),
|
|
79
|
+
integrityTarget: fieldValue(integrity, 'Integrity Target')
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function correlateWorkspaceRepresentationFacts(markdown, facts, findings, path) {
|
|
84
|
+
if (!facts || facts.factsFormat !== 'portable-recipient-v2' || Number(facts.factsVersion || 0) !== 1) return;
|
|
85
|
+
const visible = parseRecipientV2WorkspaceRepresentation(markdown);
|
|
86
|
+
const checks = [
|
|
87
|
+
['workspaceArtifactPath', visible.workspaceArtifactPath],
|
|
88
|
+
['payloadArtifactPath', visible.payloadArtifactPath],
|
|
89
|
+
['sourceWorkspaceTargetInnerPath', visible.workspaceArtifactInnerPath],
|
|
90
|
+
['coverage', visible.coverage]
|
|
91
|
+
];
|
|
92
|
+
for (const [key, observed] of checks) if (facts[key] && String(facts[key]) !== String(observed || '')) findings.push(finding('error', `portable.handoff-v2-surface.workspace-representation.visible-${key}-mismatch`, 'Workspace Representation visible semantic field diverges from its transport tamper-check facts.', { path, field: key }));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function inspectWorkspaceRepresentationShape(markdown, findings, path) {
|
|
96
|
+
const required = {
|
|
97
|
+
'Representation Binding': ['Workspace Artifact','Representation Payload','Representation Kind','Coverage','Binding State'],
|
|
98
|
+
'Representation Correlation': ['Workspace Tree Root','Workspace Artifact Inner Path','Archive Entry Root','Path Mapping','Collision Policy','Decoder Requirement'],
|
|
99
|
+
'Provider Qualification': ['Activation Rule','Payload Integrity Requirement','Coverage Requirement','Staleness Rule','Selection Rule','Multi-Workspace Isolation'],
|
|
100
|
+
'Relation Boundary': ['Parent Boundary','Workspace Identity Boundary','Payload Identity Boundary','Transport Boundary','Outer Integrity Boundary'],
|
|
101
|
+
'Interpretation Limits': ['Does Not Prove','Must Not Be Used As']
|
|
102
|
+
};
|
|
103
|
+
for (const [section, fields] of Object.entries(required)) {
|
|
104
|
+
const text = sectionText(markdown, section);
|
|
105
|
+
if (!text) { findings.push(finding('error', 'portable.handoff-v2-surface.workspace-representation.section-missing', `Workspace Representation artifact is missing required section ${section}.`, { path, section })); continue; }
|
|
106
|
+
for (const field of fields) if (!fieldValue(text, field)) findings.push(finding('error', 'portable.handoff-v2-surface.workspace-representation.field-missing', `Workspace Representation artifact is missing required field ${field}.`, { path, section, field }));
|
|
107
|
+
}
|
|
108
|
+
const parsed = parseRecipientV2WorkspaceRepresentation(markdown);
|
|
109
|
+
const contract = parsed.coverage === 'bounded' ? BOUNDED_CONTRACT : COMPLETE_CONTRACT;
|
|
110
|
+
const fixed = {
|
|
111
|
+
representationKind: contract.representationKind,
|
|
112
|
+
workspaceTreeRoot: '.', archiveEntryRoot: '.', pathMapping: 'identity-relative-paths', collisionPolicy: 'reject-ambiguous-or-unsafe-paths',
|
|
113
|
+
activationRule: contract.activationRule, payloadIntegrityRequirement: 'verified-exact-payload-bytes', coverageRequirement: contract.coverageRequirement,
|
|
114
|
+
stalenessRule: 'requalify-on-binding-relevant-change', selectionRule: contract.selectionRule, multiWorkspaceIsolation: 'independent-binding-closure'
|
|
115
|
+
};
|
|
116
|
+
if (!['complete', 'bounded', 'partial', 'unknown'].includes(parsed.coverage)) findings.push(finding('error', 'portable.handoff-v2-surface.workspace-representation.coverage-invalid', 'Workspace Representation coverage is outside the canonical domain.', { path, observed: parsed.coverage }));
|
|
117
|
+
if (parsed.coverage === 'bounded') {
|
|
118
|
+
const scope = {
|
|
119
|
+
scopeBasis: 'exact-representation-entry-set',
|
|
120
|
+
includedEntryAuthority: 'qualified-decoded-entry-set',
|
|
121
|
+
omittedEntryMeaning: 'outside-representation-not-absent-from-workspace',
|
|
122
|
+
sourceMembershipClaim: 'represented-entries-are-workspace-relative-source-bytes',
|
|
123
|
+
recoveryClosureBoundary: 'separate-qualified-closure'
|
|
124
|
+
};
|
|
125
|
+
for (const [key, expected] of Object.entries(scope)) if (parsed[key] !== expected) findings.push(finding('error', 'portable.handoff-v2-surface.workspace-representation.scope-contract-mismatch', 'Bounded Workspace Representation is missing or diverges from the canonical exact-scope contract.', { path, field: key, expected, observed: parsed[key] }));
|
|
126
|
+
}
|
|
127
|
+
for (const [key, expected] of Object.entries(fixed)) if (parsed[key] && parsed[key] !== expected) findings.push(finding('error', 'portable.handoff-v2-surface.workspace-representation.contract-mismatch', 'Workspace Representation artifact diverges from the canonical ready-provider contract for its coverage.', { path, field: key, expected, observed: parsed[key], coverage: parsed.coverage }));
|
|
128
|
+
if (!parsed.workspaceArtifactPath || !parsed.payloadArtifactPath) findings.push(finding('error', 'portable.handoff-v2-surface.workspace-representation.endpoint-missing', 'Workspace Representation must expose both semantic endpoints.', { path }));
|
|
129
|
+
if (parsed.pathMapping === 'manifest' && !parsed.mappingManifest) findings.push(finding('error', 'portable.handoff-v2-surface.workspace-representation.mapping-manifest-missing', 'Manifest path mapping requires an explicit Mapping Manifest.', { path }));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function renderParentEnvelope(parent = null) {
|
|
133
|
+
if (!parent) return '';
|
|
134
|
+
const path = String(parent.path || '').trim();
|
|
135
|
+
const label = String(parent.label || path || 'Parent');
|
|
136
|
+
const schemaId = String(parent.schemaId || '').trim();
|
|
137
|
+
const schemaTarget = String(parent.schemaTarget || '').trim();
|
|
138
|
+
const createdAt = normalizeCreatedAt(parent.createdAt || '');
|
|
139
|
+
if (!path || !schemaId || !schemaTarget || !String(parent.selfDigest || '').trim()) throw new Error('portable.handoff-v2-surface.parent-authority-incomplete');
|
|
140
|
+
return `- Parent\n - Parent Schema: [${schemaId}](${schemaTarget})\n - Created At: ${createdAt}\n - Trace: [${label}](${path})\n - Origin:\n - [relative](${path})\n`;
|
|
141
|
+
}
|
|
142
|
+
function renderParentIntegrity(parent = null) {
|
|
143
|
+
if (!parent) return '';
|
|
144
|
+
const path = String(parent.path || '').trim();
|
|
145
|
+
const label = String(parent.label || path || 'Parent');
|
|
146
|
+
const digest = String(parent.selfDigest || '').trim();
|
|
147
|
+
if (!path || !digest) throw new Error('portable.handoff-v2-surface.parent-integrity-incomplete');
|
|
148
|
+
return `- [sha256-base64url-c14n-v2](${C14N_V2_VALIDATOR_TARGET})\n - Towards: [${label}](${path})\n - Value: ${digest}\n\n`;
|
|
149
|
+
}
|
|
150
|
+
function markdownTarget(value = '') { return String(value || '').match(/\[[^\]]*\]\(([^)]+)\)/)?.[1] || String(value || '').trim(); }
|
|
151
|
+
function sectionText(markdown = '', heading = '') {
|
|
152
|
+
const re = new RegExp(`^##\\s+${escapeRe(heading)}\\s*$`, 'mi');
|
|
153
|
+
const match = re.exec(String(markdown || ''));
|
|
154
|
+
if (!match) return '';
|
|
155
|
+
const rest = String(markdown || '').slice(match.index + match[0].length);
|
|
156
|
+
const next = /^##\s+/m.exec(rest);
|
|
157
|
+
return (next ? rest.slice(0, next.index) : rest).trim();
|
|
158
|
+
}
|
|
159
|
+
function fieldValue(section = '', name = '') { const m = String(section || '').match(new RegExp(`^\\s*-\\s+${escapeRe(name)}:\\s*(.+?)\\s*$`, 'mi')); return String(m?.[1] || '').trim(); }
|
|
160
|
+
function seal(unsigned) { const result = sealC14nV2Self(unsigned); if (result.state !== 'sealed') throw new Error(`portable.handoff-v2-surface.integrity.seal-failed:${result.reason || result.state}`); return `${result.markdown}\n`; }
|
|
161
|
+
function normalizeCreatedAt(value = '') { const text = String(value || '').trim(); if (!text) return '1970-01-01 00:00:00'; return text.replace('T', ' ').replace(/\.\d{3}Z$/, '').replace(/Z$/, '').slice(0, 19); }
|
|
162
|
+
function escapeRe(value = '') { return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
|
|
163
|
+
function finding(severity, code, message, extra = {}) { return Object.freeze({ severity, code, message, ...extra }); }
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { validateArtifact } from '../../../validation/validateArtifact.js';
|
|
2
|
+
import { C14N_V2_METHOD_ID, canonicalC14nV2SelfState, verifyC14nV2TargetSelfDigest } from '../../../integrity/integrity.c14nV2.js';
|
|
3
|
+
import { portableRuntimeValidationContractForSchema } from '../schema/qualifiedLocalRoot.runtime.js';
|
|
4
|
+
|
|
5
|
+
export const HANDOFF_ROUTE_ARTIFACT_CONFORMANCE_SCHEMA_ID = 'tiinex.portable.handoff-route-artifact-conformance.v1';
|
|
6
|
+
|
|
7
|
+
const QUALIFIED_CONTRACT_STATES = new Set(['valid', 'valid-with-preserved-unknowns']);
|
|
8
|
+
|
|
9
|
+
export function qualifyTiinexRouteArtifact(input = {}) {
|
|
10
|
+
const markdown = String(input.markdown || '');
|
|
11
|
+
const expectedSchemaId = String(input.expectedSchemaId || '').trim();
|
|
12
|
+
const requireExactContract = input.requireExactContract !== false;
|
|
13
|
+
const runtimeProjection = portableRuntimeValidationContractForSchema(expectedSchemaId);
|
|
14
|
+
const validation = validateArtifact({ markdown, validationContractOverride: runtimeProjection.state === 'qualified' ? runtimeProjection.compiledContract : null });
|
|
15
|
+
const parsed = validation.parsed || {};
|
|
16
|
+
const findings = [];
|
|
17
|
+
|
|
18
|
+
if (!expectedSchemaId) findings.push(finding('error', 'portable.route-artifact.expected-schema.missing', 'Route artifact qualification requires an expected declared schema identifier.'));
|
|
19
|
+
else if (String(validation.schemaId || '') !== expectedSchemaId) findings.push(finding('error', 'portable.route-artifact.schema.mismatch', `Route artifact declares ${validation.schemaId || 'no Current Schema'} instead of required ${expectedSchemaId}.`, { expectedSchemaId, observedSchemaId: String(validation.schemaId || '') }));
|
|
20
|
+
|
|
21
|
+
for (const item of validation.findings || []) {
|
|
22
|
+
if (item.severity !== 'error') continue;
|
|
23
|
+
findings.push(finding('error', item.code || 'portable.route-artifact.validation.error', item.message || 'Declared Tiinex contract validation failed.', { source: item.source || '', qualification: item.qualification || '' }));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (requireExactContract) {
|
|
27
|
+
if (!validation.contractValidation?.available) findings.push(finding('error', 'portable.route-artifact.contract.unavailable', `Exact registered contract validation is unavailable for ${expectedSchemaId || validation.schemaId || 'the declared schema'}.`));
|
|
28
|
+
else if (!QUALIFIED_CONTRACT_STATES.has(String(validation.contractValidation.state || ''))) {
|
|
29
|
+
findings.push(finding('error', 'portable.route-artifact.contract.unqualified', `Declared Tiinex contract did not qualify: ${validation.contractValidation.state || 'unknown'}.`, { contractState: String(validation.contractValidation.state || '') }));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const selfIntegrity = canonicalC14nV2SelfState(markdown);
|
|
34
|
+
if (selfIntegrity.state !== 'verified') findings.push(finding('error', 'portable.route-artifact.integrity.self.unverified', `Exact route artifact self integrity is not verified: ${selfIntegrity.reason || selfIntegrity.state}.`, { integrityState: selfIntegrity.state, reason: selfIntegrity.reason || '' }));
|
|
35
|
+
|
|
36
|
+
const parentQualification = qualifyParentContinuity({ parsed, markdown, resolveParent: input.resolveParent, parentMarkdown: input.parentMarkdown });
|
|
37
|
+
findings.push(...parentQualification.findings);
|
|
38
|
+
|
|
39
|
+
const status = findings.some((item) => item.severity === 'error') ? 'blocked' : 'qualified';
|
|
40
|
+
return deepFreeze({
|
|
41
|
+
schema: HANDOFF_ROUTE_ARTIFACT_CONFORMANCE_SCHEMA_ID,
|
|
42
|
+
version: 1,
|
|
43
|
+
status,
|
|
44
|
+
expectedSchemaId,
|
|
45
|
+
observedSchemaId: String(validation.schemaId || ''),
|
|
46
|
+
contractState: validation.contractValidation?.available ? String(validation.contractValidation.state || 'unknown') : 'unavailable',
|
|
47
|
+
validationState: String(validation.validation?.state || 'unknown'),
|
|
48
|
+
selfIntegrity: projectSelfIntegrity(selfIntegrity),
|
|
49
|
+
parentContinuity: parentQualification.projection,
|
|
50
|
+
findings: Object.freeze(findings),
|
|
51
|
+
boundary: 'Exact-byte Tiinex route-artifact qualification. Registered schema/Root validation and independently recomputed continuity integrity are qualification requirements; stored footer equality, package placement, filename, and carrier projections cannot override a schema or integrity failure.'
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function qualifySelectedHandoffArtifact(input = {}) {
|
|
56
|
+
return qualifyTiinexRouteArtifact({ ...input, expectedSchemaId: 'tiinex.handoff.v1', requireExactContract: true });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function qualifyParentContinuity({ parsed = {}, resolveParent, parentMarkdown = '' } = {}) {
|
|
60
|
+
const findings = [];
|
|
61
|
+
const parent = parsed?.envelope?.parent || {};
|
|
62
|
+
const parentDeclared = Boolean(parent?.schema?.id || parent?.createdAt || parent?.trace || parent?.origin || parent?.originEntries?.length);
|
|
63
|
+
if (!parentDeclared) return Object.freeze({ projection: Object.freeze({ state: 'not-required', parentDeclared: false, targetEntry: null, targetResolution: null }), findings: Object.freeze([]) });
|
|
64
|
+
|
|
65
|
+
const targetEntries = (parsed?.integrity?.entries || []).filter((entry) => entry?.method === C14N_V2_METHOD_ID && entry?.towards && entry.towards !== 'self');
|
|
66
|
+
const authorityTargets = parentAuthorityTargets(parent);
|
|
67
|
+
const authorityMatches = targetEntries.filter((entry) => authorityTargets.includes(String(entry.towards || '')));
|
|
68
|
+
let targetEntry = null;
|
|
69
|
+
if (authorityMatches.length === 1) targetEntry = authorityMatches[0];
|
|
70
|
+
else if (!authorityMatches.length && targetEntries.length === 1) targetEntry = targetEntries[0];
|
|
71
|
+
else if (!targetEntries.length) findings.push(finding('error', 'portable.route-artifact.integrity.parent-target.missing', 'Parent-bearing route artifact is missing a c14n-v2 Parent-target integrity entry.'));
|
|
72
|
+
else findings.push(finding('error', 'portable.route-artifact.integrity.parent-target.ambiguous', 'Parent-bearing route artifact has no unique c14n-v2 Parent-target integrity entry.', { targetEntryCount: targetEntries.length, authorityMatchCount: authorityMatches.length }));
|
|
73
|
+
|
|
74
|
+
let targetResolution = null;
|
|
75
|
+
if (targetEntry) {
|
|
76
|
+
if (typeof resolveParent === 'function') {
|
|
77
|
+
try { targetResolution = resolveParent({ parsed, parent, targetEntry }) || null; }
|
|
78
|
+
catch (error) { targetResolution = Object.freeze({ state: 'error', reason: String(error?.message || error || 'parent-resolution-failed') }); }
|
|
79
|
+
} else if (parentMarkdown) {
|
|
80
|
+
targetResolution = Object.freeze({ state: 'qualified', markdown: String(parentMarkdown), basis: 'supplied-parent-markdown' });
|
|
81
|
+
}
|
|
82
|
+
if (!targetResolution || targetResolution.state !== 'qualified' || !targetResolution.markdown) {
|
|
83
|
+
findings.push(finding('error', 'portable.route-artifact.integrity.parent-target.unresolved', 'Parent-target integrity cannot be independently qualified because the exact Parent representation is unavailable or ambiguous.', { targetState: String(targetResolution?.state || 'unavailable'), reason: String(targetResolution?.reason || '') }));
|
|
84
|
+
} else {
|
|
85
|
+
const verification = verifyC14nV2TargetSelfDigest({ value: targetEntry.value, targetMarkdown: targetResolution.markdown });
|
|
86
|
+
targetResolution = Object.freeze({ ...targetResolution, verification });
|
|
87
|
+
if (verification.state !== 'verified') findings.push(finding('error', 'portable.route-artifact.integrity.parent-target.unverified', `Parent-target integrity is not verified against the exact Parent representation: ${verification.reason || verification.state}.`, { targetState: verification.state, reason: verification.reason || '' }));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return Object.freeze({
|
|
92
|
+
projection: deepFreeze({
|
|
93
|
+
state: findings.some((item) => item.severity === 'error') ? 'blocked' : 'qualified',
|
|
94
|
+
parentDeclared: true,
|
|
95
|
+
parentSchemaId: String(parent?.schema?.id || ''),
|
|
96
|
+
trace: String(parent?.trace || ''),
|
|
97
|
+
authorityTargets: Object.freeze(authorityTargets),
|
|
98
|
+
targetEntry: targetEntry ? Object.freeze({ method: targetEntry.method, towards: targetEntry.towards, value: targetEntry.value }) : null,
|
|
99
|
+
targetResolution: targetResolution ? projectTargetResolution(targetResolution) : null
|
|
100
|
+
}),
|
|
101
|
+
findings: Object.freeze(findings)
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function parentAuthorityTargets(parent = {}) {
|
|
106
|
+
const targets = [];
|
|
107
|
+
for (const entry of parent.originEntries || []) if (String(entry?.label || '').trim() === 'browse + git' && entry?.target) targets.push(String(entry.target));
|
|
108
|
+
if (parent.trace) targets.push(String(parent.trace));
|
|
109
|
+
return [...new Set(targets.filter(Boolean))];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function projectSelfIntegrity(state = {}) {
|
|
113
|
+
return Object.freeze({ state: String(state.state || 'unknown'), reason: String(state.reason || ''), declaredValue: String(state.declaredValue || ''), computedValue: String(state.computedValue || '') });
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function projectTargetResolution(value = {}) {
|
|
117
|
+
return Object.freeze({
|
|
118
|
+
state: String(value.state || 'unknown'),
|
|
119
|
+
reason: String(value.reason || ''),
|
|
120
|
+
basis: String(value.basis || ''),
|
|
121
|
+
workspaceRelativePath: String(value.workspaceRelativePath || ''),
|
|
122
|
+
packagePath: String(value.packagePath || ''),
|
|
123
|
+
sha256: String(value.sha256 || ''),
|
|
124
|
+
verification: value.verification ? Object.freeze({ state: String(value.verification.state || ''), reason: String(value.verification.reason || ''), expectedValue: String(value.verification.expectedValue || ''), targetValue: String(value.verification.targetValue || ''), computedTargetValue: String(value.verification.computedTargetValue || '') }) : null
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
function finding(severity, code, message, extra = {}) { return Object.freeze({ severity, code, message, ...extra }); }
|
|
130
|
+
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,67 @@
|
|
|
1
|
+
import { packageFileBytes, sha256Hex } from '../../../export/package.bytes.js';
|
|
2
|
+
|
|
3
|
+
export const PORTABLE_TOOLING_BOOTSTRAP_MANIFEST_PATH = 'tiinex.bootstrap/manifest.json';
|
|
4
|
+
export const PORTABLE_TOOLING_BOOTSTRAP_MANIFEST_SCHEMA_ID = 'tiinex.portable.tooling-bootstrap.manifest.v1';
|
|
5
|
+
|
|
6
|
+
export function inspectPortableToolingBootstrap(bundle = {}) {
|
|
7
|
+
const files = Array.isArray(bundle.files) ? bundle.files : [];
|
|
8
|
+
const byPath = new Map(files.map((file) => [String(file.path || ''), file]));
|
|
9
|
+
const findings = [];
|
|
10
|
+
const manifestFile = byPath.get(PORTABLE_TOOLING_BOOTSTRAP_MANIFEST_PATH);
|
|
11
|
+
const manifest = parseJsonFile(manifestFile);
|
|
12
|
+
if (!manifest) findings.push(finding('error', 'portable.tooling-bootstrap.manifest.missing', 'Portable Tooling bootstrap manifest is missing or unreadable.'));
|
|
13
|
+
else if (String(manifest.schema || '') !== PORTABLE_TOOLING_BOOTSTRAP_MANIFEST_SCHEMA_ID) findings.push(finding('error', 'portable.tooling-bootstrap.manifest.schema', 'Portable Tooling bootstrap manifest schema is unsupported.', { actual: manifest.schema || '' }));
|
|
14
|
+
|
|
15
|
+
const delivery = String(manifest?.delivery || '');
|
|
16
|
+
const entrypoint = String(manifest?.entrypoint || '').trim();
|
|
17
|
+
if (manifest && !['embedded', 'persistent'].includes(delivery)) findings.push(finding('error', 'portable.tooling-bootstrap.delivery.unsupported', 'Portable Tooling bootstrap delivery mode is unsupported.', { delivery }));
|
|
18
|
+
if (manifest && !entrypoint) findings.push(finding('error', 'portable.tooling-bootstrap.entrypoint.missing', 'Portable Tooling bootstrap manifest must declare one exact runtime entrypoint.'));
|
|
19
|
+
else if (entrypoint && (!entrypoint.startsWith('runtime/') || entrypoint.includes('..'))) findings.push(finding('error', 'portable.tooling-bootstrap.entrypoint.invalid', 'Portable Tooling bootstrap entrypoint must be one normalized runtime-relative path.', { entrypoint }));
|
|
20
|
+
const declared = new Map();
|
|
21
|
+
for (const entry of manifest?.runtime?.entries || []) {
|
|
22
|
+
const relative = String(entry.path || '');
|
|
23
|
+
const packagePath = `tiinex.bootstrap/${relative}`;
|
|
24
|
+
if (!relative.startsWith('runtime/') || declared.has(packagePath)) {
|
|
25
|
+
findings.push(finding('error', 'portable.tooling-bootstrap.entry.invalid', 'Bootstrap runtime manifest contains an invalid or duplicate runtime entry.', { path: relative }));
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
declared.set(packagePath, entry);
|
|
29
|
+
if (delivery !== 'embedded') continue;
|
|
30
|
+
const file = byPath.get(packagePath);
|
|
31
|
+
if (!file) {
|
|
32
|
+
findings.push(finding('error', 'portable.tooling-bootstrap.runtime.missing', 'Embedded Tooling bootstrap runtime entry is missing from package bytes.', { path: packagePath }));
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const data = packageFileBytes(file);
|
|
36
|
+
if (Number(entry.bytes || 0) !== data.byteLength) findings.push(finding('error', 'portable.tooling-bootstrap.runtime.bytes-mismatch', 'Embedded Tooling bootstrap runtime byte length differs from its manifest.', { path: packagePath }));
|
|
37
|
+
if (String(entry.sha256 || '') !== sha256Hex(data)) findings.push(finding('error', 'portable.tooling-bootstrap.runtime.sha256-mismatch', 'Embedded Tooling bootstrap runtime digest differs from its manifest.', { path: packagePath }));
|
|
38
|
+
}
|
|
39
|
+
const entrypointPackagePath = entrypoint ? `tiinex.bootstrap/${entrypoint}` : '';
|
|
40
|
+
if (entrypointPackagePath && !declared.has(entrypointPackagePath)) findings.push(finding('error', 'portable.tooling-bootstrap.entrypoint.unlisted', 'Portable Tooling bootstrap entrypoint is not present in the exact manifest-declared runtime representation.', { entrypoint }));
|
|
41
|
+
const runtimeFiles = files.filter((file) => String(file.path || '').startsWith('tiinex.bootstrap/runtime/'));
|
|
42
|
+
if (delivery === 'embedded') {
|
|
43
|
+
for (const file of runtimeFiles) if (!declared.has(String(file.path || ''))) findings.push(finding('error', 'portable.tooling-bootstrap.runtime.unlisted', 'A package byte is colocated under the bootstrap runtime prefix but is not granted bootstrap authority by the manifest.', { path: file.path || '' }));
|
|
44
|
+
if (runtimeFiles.length !== declared.size) findings.push(finding('error', 'portable.tooling-bootstrap.runtime.cardinality', 'Embedded Tooling bootstrap runtime cardinality differs from its manifest.', { declared: declared.size, supplied: runtimeFiles.length }));
|
|
45
|
+
} else if (delivery === 'persistent' && runtimeFiles.length) {
|
|
46
|
+
findings.push(finding('error', 'portable.tooling-bootstrap.persistent.embedded-bytes', 'Persistent Tooling bootstrap mode must not silently embed runtime bytes.', { supplied: runtimeFiles.length }));
|
|
47
|
+
}
|
|
48
|
+
const representation = manifest?.runtime?.entries || [];
|
|
49
|
+
const representationSha256 = sha256Text(stableJson(representation));
|
|
50
|
+
if (manifest && String(manifest.runtime?.representationSha256 || '') !== representationSha256) findings.push(finding('error', 'portable.tooling-bootstrap.runtime.representation-mismatch', 'Tooling bootstrap runtime representation digest differs from the declared manifest entries.'));
|
|
51
|
+
return Object.freeze({
|
|
52
|
+
schema: 'tiinex.portable.tooling-bootstrap.inspection.v1',
|
|
53
|
+
status: findings.some((item) => item.severity === 'error') ? 'invalid' : 'valid',
|
|
54
|
+
delivery: delivery || 'unknown',
|
|
55
|
+
manifest,
|
|
56
|
+
entrypoint: entrypoint ? Object.freeze({ path: entrypoint, packagePath: entrypointPackagePath, state: declared.has(entrypointPackagePath) ? 'qualified' : 'unqualified' }) : null,
|
|
57
|
+
counts: Object.freeze({ declaredRuntimeFiles: declared.size, suppliedRuntimeFiles: runtimeFiles.length, findings: findings.length, errors: findings.filter((item) => item.severity === 'error').length }),
|
|
58
|
+
qualification: Object.freeze({ exactManifestMembershipRequired: true, exactEntrypointManifestMembershipRequired: true, filenameOrColocationAuthority: false, ordinaryWorkspaceBytesAreBootstrapAuthority: false }),
|
|
59
|
+
findings: Object.freeze(findings)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function parseJsonFile(file) { if (!file) return null; try { return JSON.parse(new TextDecoder().decode(packageFileBytes(file))); } catch { return null; } }
|
|
64
|
+
function finding(severity, code, message, extra = {}) { return Object.freeze({ severity, code, message, ...extra }); }
|
|
65
|
+
function sha256Text(value = '') { const bytes = new TextEncoder().encode(String(value)); return sha256Hex(bytes); }
|
|
66
|
+
function stableJson(value) { return JSON.stringify(sortJson(value)); }
|
|
67
|
+
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])])); }
|